From 5e1d70a839cc8dd21a3d3b972cebd83ad213ce94 Mon Sep 17 00:00:00 2001 From: zhanghonggeng Date: Thu, 24 Jul 2025 06:13:15 +0000 Subject: [PATCH 1/6] update slice-check --- paddle/fluid/pybind/eager_method.cc | 9 --------- paddle/fluid/pybind/slice_utils.h | 30 +++++++++++++++++------------ 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/paddle/fluid/pybind/eager_method.cc b/paddle/fluid/pybind/eager_method.cc index dfe41a7e006e96..40455c8fe55c2b 100644 --- a/paddle/fluid/pybind/eager_method.cc +++ b/paddle/fluid/pybind/eager_method.cc @@ -1601,19 +1601,10 @@ static PyObject* tensor__getitem_dygraph(TensorObject* self, &trans_dim, &out_is_view); - bool has_bool_index = false; - for (auto& index : transed_index) { - if (index.dtype() == phi::DataType::BOOL) { - has_bool_index = true; - } - } const int index_size = PyTuple_GET_SIZE(index_ptr); - const bool is_combined_bool = has_bool_index && index_size > 1; - ApplyGetitem(index_size, pos_of_new_dim, rank_of_new_dim, - is_combined_bool, &transed_index, &tensor, &self->tensor, diff --git a/paddle/fluid/pybind/slice_utils.h b/paddle/fluid/pybind/slice_utils.h index 07bea224531ff0..cbb50fd7f7b188 100644 --- a/paddle/fluid/pybind/slice_utils.h +++ b/paddle/fluid/pybind/slice_utils.h @@ -695,8 +695,7 @@ static paddle::Tensor dealWithAdvancedIndex( transed_tensor = tensor; } else { *out_is_view = true; - if (FLAGS_use_stride_kernel && *pos_of_new_dim != 0 && - (is_for_setitem || int_tensor_only)) { + if (FLAGS_use_stride_kernel && *pos_of_new_dim != 0) { transed_tensor = tensor; } else { transed_tensor = transpose_ad_func(tensor, *trans_dim); @@ -731,9 +730,10 @@ static std::vector PrepareIndices( } static paddle::Tensor getValueForBoolTensor(const paddle::Tensor& tensor, + const paddle::Tensor& self_tensor, const paddle::Tensor& bool_index, const int64_t slice_offset, - const bool is_combined_bool) { + const int64_t pos_of_new_dim) { PADDLE_ENFORCE(bool_index.shape().size() <= tensor.shape().size(), common::errors::InvalidArgument( "The dims of bool index doesn't match indexed array, " @@ -757,8 +757,8 @@ static paddle::Tensor getValueForBoolTensor(const paddle::Tensor& tensor, } const phi::distributed::ProcessMesh* mesh = nullptr; - if (InputsContainDistTensor(&mesh, tensor, bool_index)) { - ConvertAllInputsToDistTensor(mesh, tensor, bool_index); + if (InputsContainDistTensor(&mesh, tensor, self_tensor, bool_index)) { + ConvertAllInputsToDistTensor(mesh, tensor, self_tensor, bool_index); } if (bool_index.shape().size() == tensor_shape.size()) { @@ -766,11 +766,14 @@ static paddle::Tensor getValueForBoolTensor(const paddle::Tensor& tensor, } auto bool_2_idx = nonzero_ad_func(bool_index); - if (FLAGS_use_stride_kernel && !is_combined_bool) { + if (FLAGS_use_stride_kernel) { std::vector indices = PrepareIndices(tensor, bool_2_idx, bool_index); + for (int i = 0; i < pos_of_new_dim; ++i) { + indices.insert(indices.begin(), paddle::Tensor()); + } while (indices.size() < static_cast(tensor.dims().size())) { - indices.emplace_back(); + indices.emplace_back(paddle::Tensor()); } std::vector indices_int64; @@ -784,7 +787,7 @@ static paddle::Tensor getValueForBoolTensor(const paddle::Tensor& tensor, AdvancedIndex ad = AdvancedIndex(tensor, indices_int64); const bool accumulate = false; - return index_elementwise_get_ad_func(tensor, + return index_elementwise_get_ad_func(self_tensor, ad.indices, ad.src_sizes, ad.src_strides, @@ -1172,7 +1175,6 @@ static void ApplySetitem(const std::vector trans_dim, static void ApplyGetitem(const int index_size, const int pos_of_new_dim, const int rank_of_new_dim, - const bool is_combined_bool, std::vector* transed_index, paddle::Tensor* tensor, paddle::Tensor* self_tensor, @@ -1202,8 +1204,11 @@ static void ApplyGetitem(const int index_size, (*transed_index)[0].dtype() == phi::DataType::BOOL) { // get value for bool tensor int64_t slice_offset = 0; - *out = getValueForBoolTensor( - *transed_tensor, (*transed_index)[0], slice_offset, is_combined_bool); + *out = getValueForBoolTensor(*transed_tensor, + (*self_tensor), + (*transed_index)[0], + slice_offset, + pos_of_new_dim); } else { // get value for int tensor ParseBoolAndBroadcastIndices(transed_index); @@ -1215,7 +1220,7 @@ static void ApplyGetitem(const int index_size, } } - if (FLAGS_use_stride_kernel && !is_combined_bool && !has_empty_index) { + if (FLAGS_use_stride_kernel && !has_empty_index) { const phi::distributed::ProcessMesh* mesh = nullptr; if (InputsContainDistTensor( &mesh, *self_tensor, *transed_tensor, *transed_index)) { @@ -1223,6 +1228,7 @@ static void ApplyGetitem(const int index_size, mesh, *self_tensor, *transed_tensor, *transed_index); } + *transed_index = expandTensors(*transed_index); *transed_index = expand_outplace(*transed_index); std::vector transed_index_int64; From 18e447ec65ac701aa4c16e0007527bf4fcf99d05 Mon Sep 17 00:00:00 2001 From: zhouxin Date: Wed, 30 Jul 2025 12:23:47 +0000 Subject: [PATCH 2/6] pass --- paddle/fluid/pybind/slice_utils.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/paddle/fluid/pybind/slice_utils.h b/paddle/fluid/pybind/slice_utils.h index cbb50fd7f7b188..3fecb3c1af3ba4 100644 --- a/paddle/fluid/pybind/slice_utils.h +++ b/paddle/fluid/pybind/slice_utils.h @@ -17,6 +17,7 @@ #include #include +#include #include "paddle/fluid/eager/api/all.h" #include "paddle/fluid/eager/api/generated/eager_generated/forwards/dygraph_functions.h" #include "paddle/fluid/eager/utils.h" @@ -30,6 +31,7 @@ #include "paddle/phi/kernels/funcs/common_infer_shape_functions.h" #include "paddle/phi/kernels/funcs/slice_utils.h" #include "paddle/phi/kernels/funcs/strided_slice.h" +#include "paddle/utils/pybind.h" #include "pybind11/numpy.h" #include "pybind11/pybind11.h" #include "pybind11/stl.h" @@ -746,12 +748,12 @@ static paddle::Tensor getValueForBoolTensor(const paddle::Tensor& tensor, while (i < bool_index.shape().size()) { PADDLE_ENFORCE_EQ( bool_index.shape()[i], - tensor_shape[i], + tensor_shape[i + pos_of_new_dim], common::errors::OutOfRange( "The dimension of bool index doesn't match indexed array along " "dimension %d, the target dimension is %d, but received %d", i, - tensor_shape[i], + tensor_shape[i + pos_of_new_dim], bool_index.shape()[i])); i++; } @@ -786,6 +788,9 @@ static paddle::Tensor getValueForBoolTensor(const paddle::Tensor& tensor, AdvancedIndex ad = AdvancedIndex(tensor, indices_int64); const bool accumulate = false; + const int64_t input_offset_bytes = + reinterpret_cast(tensor.data()) - + reinterpret_cast(self_tensor.data()); return index_elementwise_get_ad_func(self_tensor, ad.indices, @@ -793,7 +798,7 @@ static paddle::Tensor getValueForBoolTensor(const paddle::Tensor& tensor, ad.src_strides, ad.indexed_sizes, ad.indexed_strides, - slice_offset, + input_offset_bytes, accumulate); } else { if (bool_index.shape().size() == 1) @@ -1209,6 +1214,7 @@ static void ApplyGetitem(const int index_size, (*transed_index)[0], slice_offset, pos_of_new_dim); + return; } else { // get value for int tensor ParseBoolAndBroadcastIndices(transed_index); @@ -1283,7 +1289,6 @@ static void ApplyGetitem(const int index_size, return; } } - handle_transpose(*out); } From 09466e122d18665e2a1ae1b15f71d1eeb782d607 Mon Sep 17 00:00:00 2001 From: zhouxin Date: Thu, 31 Jul 2025 06:44:46 +0000 Subject: [PATCH 3/6] Refine and Add ut --- paddle/fluid/pybind/slice_utils.h | 9 ++++----- test/indexing/test_getitem_appendix.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/paddle/fluid/pybind/slice_utils.h b/paddle/fluid/pybind/slice_utils.h index 3fecb3c1af3ba4..edf5d09d3f88ed 100644 --- a/paddle/fluid/pybind/slice_utils.h +++ b/paddle/fluid/pybind/slice_utils.h @@ -788,9 +788,6 @@ static paddle::Tensor getValueForBoolTensor(const paddle::Tensor& tensor, AdvancedIndex ad = AdvancedIndex(tensor, indices_int64); const bool accumulate = false; - const int64_t input_offset_bytes = - reinterpret_cast(tensor.data()) - - reinterpret_cast(self_tensor.data()); return index_elementwise_get_ad_func(self_tensor, ad.indices, @@ -798,7 +795,7 @@ static paddle::Tensor getValueForBoolTensor(const paddle::Tensor& tensor, ad.src_strides, ad.indexed_sizes, ad.indexed_strides, - input_offset_bytes, + slice_offset, accumulate); } else { if (bool_index.shape().size() == 1) @@ -1208,7 +1205,9 @@ static void ApplyGetitem(const int index_size, if (transed_index->size() == 1 && (*transed_index)[0].dtype() == phi::DataType::BOOL) { // get value for bool tensor - int64_t slice_offset = 0; + const int64_t slice_offset = + reinterpret_cast(transed_tensor->data()) - + reinterpret_cast(self_tensor->data()); *out = getValueForBoolTensor(*transed_tensor, (*self_tensor), (*transed_index)[0], diff --git a/test/indexing/test_getitem_appendix.py b/test/indexing/test_getitem_appendix.py index fdd012613065ac..45490300b75c7d 100644 --- a/test/indexing/test_getitem_appendix.py +++ b/test/indexing/test_getitem_appendix.py @@ -230,6 +230,16 @@ def test_combined(self): # case 6: # [[[4 , 5 ],[10, 11],[16, 17],[22, 23]]] self.accuracy_check(x[[True, False], :, -1], y[[True, False], :, -1]) + # case 7: + # [[0, 3, 4, 5], [24, 26, 28, 29]] + index_np = np.array([[True, False], [False, True], [True, True]]) + index_paddle = paddle.to_tensor(index_np) + self.accuracy_check(x[:, 0, index_np], y[:, 0, index_paddle]) + # case 8: + # [[[[0, 1]], [[2, 3]], [[24, 25]], [[26, 27]]]] + index_np = np.array([[0], [1]]) + index_paddle = paddle.to_tensor(index_np) + self.accuracy_check(x[:, 0, index_np], y[:, 0, index_paddle]) class Test0DTensorIndexing(unittest.TestCase): From 793cfa6fd4e3cab8d70086d07a1e5241207e46cb Mon Sep 17 00:00:00 2001 From: zhouxin Date: Thu, 31 Jul 2025 11:24:17 +0000 Subject: [PATCH 4/6] Rerun CI From 926c5a650f67274fffcf0f7b8c8b9fd775a774c0 Mon Sep 17 00:00:00 2001 From: zhouxin Date: Wed, 23 Jul 2025 16:37:42 +0800 Subject: [PATCH 5/6] Fix multi-dim bool tensor index --- paddle/fluid/pybind/slice_utils.h | 60 +++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/paddle/fluid/pybind/slice_utils.h b/paddle/fluid/pybind/slice_utils.h index edf5d09d3f88ed..3260257c6260e7 100644 --- a/paddle/fluid/pybind/slice_utils.h +++ b/paddle/fluid/pybind/slice_utils.h @@ -521,21 +521,31 @@ static void ParseIndex(const paddle::Tensor& tensor, estimated_dim++; } } else { + *has_advanced_index = true; if (slice_tensor.dtype() == phi::DataType::BOOL) { - PADDLE_ENFORCE_EQ(slice_tensor.shape()[0], - dim_len, - common::errors::OutOfRange( - "The shape of boolean index %d did not match" - "indexed tensor %d along axis %d.", - slice_tensor.shape()[0], - dim_len, - current_dim)); + // bool tensor consumes (rank of index tensor) dimensions of input + // tensor + for (int i = 0; i < slice_tensor.shape().size(); i++) { + PADDLE_ENFORCE_EQ(slice_tensor.shape()[i], + dim_len, + common::errors::OutOfRange( + "The shape of boolean index %d did not match" + "indexed tensor %d along axis %d.", + slice_tensor.shape()[0], + dim_len, + current_dim)); + (*advanced_index_dim)[estimated_dim] = estimated_dim; + estimated_dim++; + current_dim++; + dim_len = shape[current_dim]; + } + } else { + // int tensor consumes only one dimension of input tensor + (*advanced_index_dim)[estimated_dim] = estimated_dim; + estimated_dim++; + current_dim++; } - *has_advanced_index = true; advanced_index->push_back(std::move(slice_tensor)); - (*advanced_index_dim)[estimated_dim] = estimated_dim; - estimated_dim++; - current_dim++; } } else { @@ -650,13 +660,15 @@ static paddle::Tensor dealWithAdvancedIndex( int* rank_of_new_dim, std::vector* trans_dim, bool* out_is_view) { + *rank_of_new_dim = 0; int p = 0; bool int_tensor_only = true; + for (size_t i = 0; i < advanced_index_dim->size(); ++i) { auto index_dim = (*advanced_index_dim)[i]; if (index_dim != -1) { - // size of advanced_index is same to number of non -1 element in - // advanced_index_dim + // sum of each advanced_index_tensor's rank equals to number of non -1 + // element in advanced_index_dim auto index = (*advanced_index)[p++]; if (index.dtype() == phi::DataType::BOOL) { int_tensor_only = false; @@ -673,11 +685,23 @@ static paddle::Tensor dealWithAdvancedIndex( } else { *pos_of_new_dim = std::min(index_dim, *pos_of_new_dim); } - *rank_of_new_dim = - std::max(*rank_of_new_dim, static_cast(index.shape().size())); - trans_dim->push_back(index_dim); - transed_index->push_back(std::move(index)); + if (index.dtype() == phi::DataType::BOOL) { + *rank_of_new_dim = std::max(*rank_of_new_dim, 1); + i--; + for (int j = 0; j < index.shape().size(); j++) { + i++; + index_dim = (*advanced_index_dim)[i]; + trans_dim->push_back(index_dim); + } + transed_index->push_back(std::move(index)); + } else { + *rank_of_new_dim = + std::max(*rank_of_new_dim, static_cast(index.shape().size())); + + trans_dim->push_back(index_dim); + transed_index->push_back(std::move(index)); + } } } From 52c2e05440654b995f8afa4e2e4601b025109781 Mon Sep 17 00:00:00 2001 From: zhouxin Date: Fri, 1 Aug 2025 06:06:52 +0000 Subject: [PATCH 6/6] Fix strided=0 case --- paddle/fluid/pybind/slice_utils.h | 45 ++++++++++++------- .../kernels/cpu/strided_slice_grad_kernel.cc | 1 + .../phi/kernels/strided_slice_grad_kernel.cc | 4 ++ 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/paddle/fluid/pybind/slice_utils.h b/paddle/fluid/pybind/slice_utils.h index 3260257c6260e7..9253111dd5324b 100644 --- a/paddle/fluid/pybind/slice_utils.h +++ b/paddle/fluid/pybind/slice_utils.h @@ -662,17 +662,12 @@ static paddle::Tensor dealWithAdvancedIndex( bool* out_is_view) { *rank_of_new_dim = 0; int p = 0; - bool int_tensor_only = true; - for (size_t i = 0; i < advanced_index_dim->size(); ++i) { auto index_dim = (*advanced_index_dim)[i]; if (index_dim != -1) { // sum of each advanced_index_tensor's rank equals to number of non -1 // element in advanced_index_dim auto index = (*advanced_index)[p++]; - if (index.dtype() == phi::DataType::BOOL) { - int_tensor_only = false; - } if (index_dim == 0) { // case 1: advanced indices at axis 0, the new dim will be at first. @@ -769,17 +764,32 @@ static paddle::Tensor getValueForBoolTensor(const paddle::Tensor& tensor, bool_index.shape().size())); auto tensor_shape = tensor.shape(); size_t i = 0; - while (i < bool_index.shape().size()) { - PADDLE_ENFORCE_EQ( - bool_index.shape()[i], - tensor_shape[i + pos_of_new_dim], - common::errors::OutOfRange( - "The dimension of bool index doesn't match indexed array along " - "dimension %d, the target dimension is %d, but received %d", - i, - tensor_shape[i + pos_of_new_dim], - bool_index.shape()[i])); - i++; + if (FLAGS_use_stride_kernel) { + while (i < bool_index.shape().size()) { + PADDLE_ENFORCE_EQ( + bool_index.shape()[i], + tensor_shape[i + pos_of_new_dim], + common::errors::OutOfRange( + "The dimension of bool index doesn't match indexed array along " + "dimension %d, the target dimension is %d, but received %d", + i, + tensor_shape[i + pos_of_new_dim], + bool_index.shape()[i])); + i++; + } + } else { + while (i < bool_index.shape().size()) { + PADDLE_ENFORCE_EQ( + bool_index.shape()[i], + tensor_shape[i], + common::errors::OutOfRange( + "The dimension of bool index doesn't match indexed array along " + "dimension %d, the target dimension is %d, but received %d", + i, + tensor_shape[i], + bool_index.shape()[i])); + i++; + } } const phi::distributed::ProcessMesh* mesh = nullptr; @@ -1237,6 +1247,9 @@ static void ApplyGetitem(const int index_size, (*transed_index)[0], slice_offset, pos_of_new_dim); + if (!FLAGS_use_stride_kernel) { + handle_transpose(*out); + } return; } else { // get value for int tensor diff --git a/paddle/phi/kernels/cpu/strided_slice_grad_kernel.cc b/paddle/phi/kernels/cpu/strided_slice_grad_kernel.cc index 1c15f04f7dd411..9885dbec8ae781 100644 --- a/paddle/phi/kernels/cpu/strided_slice_grad_kernel.cc +++ b/paddle/phi/kernels/cpu/strided_slice_grad_kernel.cc @@ -28,6 +28,7 @@ PD_REGISTER_KERNEL(strided_slice_raw_grad, bool, int64_t, int16_t, + int8_t, int, phi::dtype::float16, phi::dtype::bfloat16, diff --git a/paddle/phi/kernels/strided_slice_grad_kernel.cc b/paddle/phi/kernels/strided_slice_grad_kernel.cc index 8c5c90783133c9..807fef9359d4e1 100644 --- a/paddle/phi/kernels/strided_slice_grad_kernel.cc +++ b/paddle/phi/kernels/strided_slice_grad_kernel.cc @@ -49,6 +49,8 @@ PD_REGISTER_KERNEL(strided_slice_grad, phi::StridedSliceGradKernel, bool, int, + int8_t, + int16_t, int64_t, float, double, @@ -62,6 +64,8 @@ PD_REGISTER_KERNEL(strided_slice_grad, phi::StridedSliceGradKernel, bool, int, + int8_t, + int16_t, int64_t, float, double,