diff --git a/src/plugins/intel_gpu/src/graph/impls/ocl/strided_slice.cpp b/src/plugins/intel_gpu/src/graph/impls/ocl/strided_slice.cpp index 17899641ef86bc..0936d9abbf9b6e 100644 --- a/src/plugins/intel_gpu/src/graph/impls/ocl/strided_slice.cpp +++ b/src/plugins/intel_gpu/src/graph/impls/ocl/strided_slice.cpp @@ -12,11 +12,36 @@ namespace { template ::value>::type> -std::vector& pad_vector_to_size(std::vector& data, size_t size, DT value) { - for (size_t i = data.size(); i < size; ++i) { - data.push_back(static_cast(value)); +void pad_vector_to_size(std::vector& data, size_t size, DT value, const std::vector& ellipsis_mask) { + bool apply_ellipsis_mask = std::count(ellipsis_mask.begin(), ellipsis_mask.end(), 1) == 1; + if (apply_ellipsis_mask && data.size() == ellipsis_mask.size()) { + std::vector temp; + size_t ellipsis_pos1 = 0; + for (size_t i = 0; i < ellipsis_mask.size(); i++) { + if (ellipsis_mask[i] == 1) { + ellipsis_pos1 = i; + break; + } + } + + size_t dims_after = data.size() - ellipsis_pos1 - 1; + size_t ellipsis_pos2 = size - dims_after - 1;; + + for (size_t i = 0; i < ellipsis_pos1; i++) + temp.push_back(data[i]); + + for (size_t i = ellipsis_pos1; i < ellipsis_pos2 + 1; i++) + temp.push_back(value); + + for (size_t i = 1; i < size - ellipsis_pos2; i++) + temp.push_back(data[i + ellipsis_pos1]); + + data = temp; + } else { + for (size_t i = data.size(); i < size; ++i) { + data.push_back(static_cast(value)); + } } - return data; } template @@ -74,7 +99,7 @@ struct strided_slice_impl : typed_primitive_impl_ocl { // Getting data from constant inputs. There are 3 args: Begin, End, Stride if (!begin.empty() && !params.has_dynamic_tensors()) { - pad_vector_to_size(begin, dims_num, 0); + pad_vector_to_size(begin, dims_num, 0, prim->ellipsis_mask); params.begin_type = kernel_selector::base_params::ArgType::Constant; params.striding_params.push_back(begin); } else { @@ -91,7 +116,7 @@ struct strided_slice_impl : typed_primitive_impl_ocl { return offset; }; if (!end.empty() && !params.has_dynamic_tensors()) { - pad_vector_to_size(end, dims_num, 1); + pad_vector_to_size(end, dims_num, 1, prim->ellipsis_mask); params.end_type = kernel_selector::base_params::ArgType::Constant; params.striding_params.push_back(end); } else { @@ -108,7 +133,7 @@ struct strided_slice_impl : typed_primitive_impl_ocl { return offset; }; if (!strides.empty() && !params.has_dynamic_tensors()) { - pad_vector_to_size(strides, dims_num, 1); + pad_vector_to_size(strides, dims_num, 1, prim->ellipsis_mask); params.stride_type = kernel_selector::base_params::ArgType::Constant; params.striding_params.push_back(strides); } else { @@ -122,19 +147,22 @@ struct strided_slice_impl : typed_primitive_impl_ocl { auto end_mask_ = prim->end_mask; auto new_axis_mask_ = prim->new_axis_mask; auto shrink_axis_mask_ = prim->shrink_axis_mask; + auto ellipsis_mask_ = prim->ellipsis_mask; std::vector begin_mask(begin_mask_.begin(), begin_mask_.end()); std::vector end_mask(end_mask_.begin(), end_mask_.end()); std::vector new_axis_mask(new_axis_mask_.begin(), new_axis_mask_.end()); std::vector shrink_axis_mask(shrink_axis_mask_.begin(), shrink_axis_mask_.end()); + std::vector ellipsis_mask(ellipsis_mask_.begin(), ellipsis_mask_.end()); params.end_mask = std::move(end_mask); - pad_vector_to_size(params.end_mask, dims_num, 0); + pad_vector_to_size(params.end_mask, dims_num, 0, prim->ellipsis_mask); params.begin_mask = std::move(begin_mask); - pad_vector_to_size(params.begin_mask, dims_num, 0); + pad_vector_to_size(params.begin_mask, dims_num, 0, prim->ellipsis_mask); params.new_axis_mask = new_axis_mask; params.shrink_axis_mask = shrink_axis_mask; - pad_vector_to_size(params.shrink_axis_mask, dims_num, 0); + params.ellipsis_mask = ellipsis_mask; + pad_vector_to_size(params.shrink_axis_mask, dims_num, 0, prim->ellipsis_mask); std::vector logical_dims = params.inputs[0].LogicalDims(); std::reverse(logical_dims.begin(), logical_dims.end()); // get dims in bfyx order diff --git a/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/strided_slice_ref.cl b/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/strided_slice_ref.cl index 088e7f6364c469..fc71cc241d29b4 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/strided_slice_ref.cl +++ b/src/plugins/intel_gpu/src/kernel_selector/cl_kernels/strided_slice_ref.cl @@ -10,20 +10,20 @@ inline void FUNC(get_slice_step)(OPTIONAL_SHAPE_INFO_ARG int* step_batch, int* step_feature, int* step_w, int* step_z, int* step_y, int* step_x) { - const uint batch_index = 0; - const uint feature_index = 1; + const uint batch_index = DIM_IDX_BATCH; + const uint feature_index = DIM_IDX_FEATURE; #ifdef OUTPUT_LAYOUT_BFYX - const uint y_index = 2; - const uint x_index = 3; + const uint y_index = DIM_IDX_Y; + const uint x_index = DIM_IDX_X; #elif OUTPUT_LAYOUT_BFZYX - const uint z_index = 2; - const uint y_index = 3; - const uint x_index = 4; + const uint z_index = DIM_IDX_Z; + const uint y_index = DIM_IDX_Y; + const uint x_index = DIM_IDX_X; #elif OUTPUT_LAYOUT_BFWZYX - const uint w_index = 2; - const uint z_index = 3; - const uint y_index = 4; - const uint x_index = 5; + const uint w_index = DIM_IDX_W; + const uint z_index = DIM_IDX_Z; + const uint y_index = DIM_IDX_Y; + const uint x_index = DIM_IDX_X; #endif *step_batch = batch_index < STRIDE_DIMS ? stride[batch_index] : 1; @@ -55,20 +55,20 @@ inline void FUNC(get_slice_end)(OPTIONAL_SHAPE_INFO_ARG const uint out_z_num = INPUT0_SIZE_Z; const uint out_y_num = INPUT0_SIZE_Y; const uint out_x_num = INPUT0_SIZE_X; - const uint batch_index = 0; - const uint feature_index = 1; + const uint batch_index = DIM_IDX_BATCH; + const uint feature_index = DIM_IDX_FEATURE; #ifdef OUTPUT_LAYOUT_BFYX - const uint y_index = 2; - const uint x_index = 3; + const uint y_index = DIM_IDX_Y; + const uint x_index = DIM_IDX_X; #elif OUTPUT_LAYOUT_BFZYX - const uint z_index = 2; - const uint y_index = 3; - const uint x_index = 4; + const uint z_index = DIM_IDX_Z; + const uint y_index = DIM_IDX_Y; + const uint x_index = DIM_IDX_X; #elif OUTPUT_LAYOUT_BFWZYX - const uint w_index = 2; - const uint z_index = 3; - const uint y_index = 4; - const uint x_index = 5; + const uint w_index = DIM_IDX_W; + const uint z_index = DIM_IDX_Z; + const uint y_index = DIM_IDX_Y; + const uint x_index = DIM_IDX_X; #endif END_TYPE batch = batch_index < END_DIMS ? end[batch_index] : 0; END_TYPE feature = feature_index < END_DIMS ? end[feature_index] : 0; @@ -100,20 +100,20 @@ inline void FUNC(get_slice_begin)(OPTIONAL_SHAPE_INFO_ARG int* begin_batch, int* begin_feature, int* begin_w, int* begin_z, int* begin_y, int* begin_x) { - const uint batch_index = 0; - const uint feature_index = 1; + const uint batch_index = DIM_IDX_BATCH; + const uint feature_index = DIM_IDX_FEATURE; #ifdef OUTPUT_LAYOUT_BFYX - const uint y_index = 2; - const uint x_index = 3; + const uint y_index = DIM_IDX_Y; + const uint x_index = DIM_IDX_X; #elif OUTPUT_LAYOUT_BFZYX - const uint z_index = 2; - const uint y_index = 3; - const uint x_index = 4; + const uint z_index = DIM_IDX_Z; + const uint y_index = DIM_IDX_Y; + const uint x_index = DIM_IDX_X; #elif OUTPUT_LAYOUT_BFWZYX - const uint w_index = 2; - const uint z_index = 3; - const uint y_index = 4; - const uint x_index = 5; + const uint w_index = DIM_IDX_W; + const uint z_index = DIM_IDX_Z; + const uint y_index = DIM_IDX_Y; + const uint x_index = DIM_IDX_X; #endif BEGIN_TYPE batch = batch_index < BEGIN_DIMS ? begin[batch_index] : 0; @@ -160,7 +160,7 @@ inline void FUNC(calculate_index)(int* step, int* begin_num, int* end_num, const { int real_begin = *begin_num < 0 ? *begin_num + out_num : *begin_num; int real_end = *end_num < 0 ? *end_num + out_num : *end_num; - if (*step < 0) { + if (*step < 0) { real_begin = max((int)(0), min((int)(out_num - 1), real_begin)); real_end = max((int)(-1), min((int)out_num, real_end)); if (real_begin < real_end) { // for reversing @@ -388,7 +388,7 @@ KERNEL(strided_slice_ref)(OPTIONAL_SHAPE_INFO_ARG const uint input_index = INPUT0_OFFSET + (slice_begin_batch + batch * slice_steps_batch) * INPUT0_BATCH_PITCH + (slice_begin_feature + feature * slice_steps_feature) * INPUT0_FEATURE_PITCH + - #if INPUT0_LAYOUT_BFWZYX + #if INPUT0_LAYOUT_BFWZYX (slice_begin_w + w * slice_steps_w) * INPUT0_W_PITCH + (slice_begin_z + z * slice_steps_z) * INPUT0_Z_PITCH + (slice_begin_y + y * slice_steps_y) * INPUT0_Y_PITCH + diff --git a/src/plugins/intel_gpu/src/kernel_selector/kernels/strided_slice/strided_slice_kernel_ref.cpp b/src/plugins/intel_gpu/src/kernel_selector/kernels/strided_slice/strided_slice_kernel_ref.cpp index 8c3a1fecdba127..32cf318479e2b9 100644 --- a/src/plugins/intel_gpu/src/kernel_selector/kernels/strided_slice/strided_slice_kernel_ref.cpp +++ b/src/plugins/intel_gpu/src/kernel_selector/kernels/strided_slice/strided_slice_kernel_ref.cpp @@ -165,6 +165,38 @@ JitConstants StridedSliceKernelRef::GetJitConstants(const strided_slice_params& "NEW_AXIS_MODE", std::find(params.new_axis_mask.begin(), params.new_axis_mask.end(), 1) != params.new_axis_mask.end())); + std::vector dims_indexes; + bool ellipsis_mode = std::find(params.ellipsis_mask.begin(), params.ellipsis_mask.end(), 1) != params.ellipsis_mask.end(); + if (ellipsis_mode) { + size_t ellipsis_pos1 = 0; + for (size_t i = 0; i < params.ellipsis_mask.size(); i++) { + if (params.ellipsis_mask[i] == 1) { + ellipsis_pos1 = i; + break; + } + } + + const size_t output_rank = params.outputs[0].Dimentions(); + const size_t skip_dims_num = output_rank - params.ellipsis_mask.size() + 1; + int dim_counter = 0; + + for (size_t i = 0; i < ellipsis_pos1; i++) + dims_indexes.push_back(dim_counter++); + + for (size_t i = 0; i < skip_dims_num; i++) + dims_indexes.push_back(-1); + + dim_counter++; + for (size_t i = 0; i < params.ellipsis_mask.size() - ellipsis_pos1 - 1; i++) + dims_indexes.push_back(dim_counter++); + + OPENVINO_ASSERT(dims_indexes.size() == output_rank, "[GPU] Number of indexes is expected to match with output rank"); + } else { + dims_indexes.resize(params.outputs[0].Dimentions()); + std::iota(dims_indexes.begin(), dims_indexes.end(), 0); + } + makeJitConstForParam(jit, "DIM_IDX", dims_indexes); + bool shrink_mode = std::find(params.shrink_axis_mask.begin(), params.shrink_axis_mask.end(), 1) != params.shrink_axis_mask.end(); if (shrink_mode) { jit.AddConstant(MakeJitConstant("SHRINK_MODE", true)); diff --git a/src/plugins/intel_gpu/tests/functional/shared_tests_instances/single_layer_tests/strided_slice.cpp b/src/plugins/intel_gpu/tests/functional/shared_tests_instances/single_layer_tests/strided_slice.cpp index 3b56badf7145b6..5462a30a1d7776 100644 --- a/src/plugins/intel_gpu/tests/functional/shared_tests_instances/single_layer_tests/strided_slice.cpp +++ b/src/plugins/intel_gpu/tests/functional/shared_tests_instances/single_layer_tests/strided_slice.cpp @@ -152,6 +152,22 @@ std::vector ss_only_test_cases_fp32 = { { 128, 1, 1024 }})), { -1, 0, 0 }, { 0, 0, 0 }, { 1, 1, 1 }, { 0, 1, 1 }, { 0, 1, 1 }, { 0, 0, 0 }, { 1, 0, 0 }, { 0, 0, 0 } }, + StridedSliceSpecificParams{ ov::test::static_shapes_to_test_representation(std::vector({ + { 10, 10 }})), + { -4, 1 }, { -8, 0 }, { -1, 1 }, + { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } }, + StridedSliceSpecificParams{ ov::test::static_shapes_to_test_representation(std::vector({ + { 2, 2, 4, 1 }})), + { 0, 0 }, { 2, 2 }, { -1, 1 }, + { 1, 0 }, { 1, 0 }, { 0, 0 }, { 0, 0 }, { 0, 1 } }, + StridedSliceSpecificParams{ ov::test::static_shapes_to_test_representation(std::vector({ + { 2, 2, 4, 1 }})), + { 0, 0 }, { 4, 1 }, { 1, -1 }, + { 0, 1 }, { 0, 1 }, { 0, 0 }, { 0, 0 }, { 1, 0 } }, + StridedSliceSpecificParams{ ov::test::static_shapes_to_test_representation(std::vector({ + { 1, 5, 30, 30, 30 }})), + { 0, 0, 0 }, { 0, 29, 29 }, { 1, 1, 1 }, + {1, 1, 1}, {1, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 1, 0} }, }; std::vector ss_only_test_cases_i64 = { diff --git a/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/strided_slice.cpp b/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/strided_slice.cpp index 0854eaa6a8327a..b9d19a1877b94c 100644 --- a/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/strided_slice.cpp +++ b/src/plugins/intel_gpu/tests/functional/single_layer_tests/dynamic/strided_slice.cpp @@ -368,6 +368,7 @@ const std::vector testCasesCommon4D = { StridedSliceParams{ { 0, 0, 0, 20 }, { 1, 2, 30, 30 }, { 1, 1, 2, 1 }, { 0, 0, 0, 1 }, { 0, 1, 0, 1 }, { }, { }, { } }, StridedSliceParams{ { 0, 1, 2, 10 }, { 1, 5, 32, 18 }, { 1, 1, 1, 2 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 }, { }, { }, { } }, StridedSliceParams{ { 0, 0, 2, 10 }, { 1, 8, 32, 18 }, { 1, 2, 1, 2 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 }, { }, { }, { } }, + StridedSliceParams{ { 2, 10 }, { 32, 18 }, { 1, 2 }, { 1, 0 }, { 0, 1 }, { }, { }, { 1, 0 } }, }; const std::vector inputShapesDynamic4D = { @@ -396,6 +397,7 @@ const std::vector testCasesCommon5D = { StridedSliceParams{ { 0, 0, 0, 20 }, { 1, 2, 30, 30 }, { 1, 1, 2, 1 }, { 0, 0, 0, 1 }, { 0, 1, 0, 1 }, { }, { }, { } }, StridedSliceParams{ { 0, 1, 2, 10 }, { 1, 5, 32, 18 }, { 1, 1, 1, 2 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 }, { }, { }, { } }, StridedSliceParams{ { 0, 0, 2, 10 }, { 1, 8, 32, 18 }, { 1, 2, 1, 2 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 }, { }, { }, { } }, + StridedSliceParams{ { 0, 0, 2 }, { 1, 8, 32 }, { 1, 2, 1 }, { 1, 0, 1 }, { 0, 0, 0 }, { }, { }, { 0, 1, 0} }, }; const std::vector inputShapesDynamic5D = { @@ -421,6 +423,7 @@ INSTANTIATE_TEST_SUITE_P(smoke_CompareWithRefs_Common_Dynamic_5D, StridedSliceLa const std::vector testCasesCommon6D = { StridedSliceParams{ { 0, 2, 5, 4 }, { 1, 4, 28, 27 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, StridedSliceParams{ { 0, 0, 10, 20 }, { 1, 5, 28, 26 }, { 1, 1, 1, 2 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { }, { }, { } }, + StridedSliceParams{ { 0, 0, 0 }, { 0, 0, 0 }, { 1, 1, 1 }, { 0, 1, 0 }, { 0, 1, 0 }, { }, { }, { 0, 0, 1 } }, }; const std::vector inputShapesDynamic6D = {