From bfeec8be4fef69b89b2f4af93f481f4a1d1d3d06 Mon Sep 17 00:00:00 2001 From: WintersMontagne10335 <22251099@zju.edu.cn> Date: Thu, 14 Mar 2024 03:26:09 +0000 Subject: [PATCH 1/8] Add InferSymbolicShape for meshgrid --- .../paddle_op_infer_sym.cc | 33 +++++++++++++++++++ .../paddle_op_infer_sym.h | 3 ++ paddle/phi/api/yaml/ops.yaml | 1 + 3 files changed, 37 insertions(+) diff --git a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.cc b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.cc index 4d3f0222de40c9..46057879ca8c80 100644 --- a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.cc +++ b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.cc @@ -937,6 +937,39 @@ bool ExpandAsOpInferSymbolicShape( return true; } +bool MeshgridOpInferSymbolicShape(pir::Operation *op, + pir::ShapeConstraintIRAnalysis *shape_analysis) { + const auto &attributes = op->attributes(); + const symbol::TensorListShapeOrDataDimExprs &shape_data_list = + shape_analysis->GetShapeOrDataForValue(op->operand_source(0)) + .dyn_cast(); + + const symbol::ShapeOrDataDimExprs sym_shape_dim_exprs = [&] { + symbol::TensorListShapeOrDataDimExprs shape_dim_exprs_list; + std::vector vec; + + for(auto& shape_data : shape_data_list){ + if(shape_data.shape().size()==0){ + vec.emplace_back(1); + }else{ + vec.emplace_back(shape_data.shape()[0]); + } + } + + auto shape_dim_exprs=symbol::TensorShapeOrDataDimExprs(vec); + + for(auto& shape_data : shape_data_list){ + shape_dim_exprs_list.emplace_back(shape_dim_exprs); + } + + return symbol::ShapeOrDataDimExprs(shape_dim_exprs_list); + }(); + + pir::Value res = op->result(0); + shape_analysis->SetShapeOrDataForValue(res, sym_shape_dim_exprs); + return true; +} + bool SplitOpInferSymbolicShape(pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { PADDLE_THROW(phi::errors::Unimplemented( diff --git a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.h b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.h index a84d71815549b6..87c3acb4e49c79 100644 --- a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.h +++ b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.h @@ -65,6 +65,9 @@ OP_DECLARE_INFER_SYMBOLIC_SHAPE(UniqueConsecutive) OP_DECLARE_INFER_SYMBOLIC_SHAPE(Linspace) OP_DECLARE_INFER_SYMBOLIC_SHAPE(Logspace) OP_DECLARE_INFER_SYMBOLIC_SHAPE(Logsumexp) + +OP_DECLARE_INFER_SYMBOLIC_SHAPE(Meshgrid) + OP_DECLARE_INFER_SYMBOLIC_SHAPE(Min) OP_DECLARE_INFER_SYMBOLIC_SHAPE(Pad) OP_DECLARE_INFER_SYMBOLIC_SHAPE(Randint) diff --git a/paddle/phi/api/yaml/ops.yaml b/paddle/phi/api/yaml/ops.yaml index ce7d9e935247d0..57976a0789cb50 100755 --- a/paddle/phi/api/yaml/ops.yaml +++ b/paddle/phi/api/yaml/ops.yaml @@ -1960,6 +1960,7 @@ func : meshgrid data_type : inputs backward : meshgrid_grad + interfaces : paddle::dialect::InferSymbolicShapeInterface - op : mode args : (Tensor x, int axis = -1, bool keepdim = false) From 3616eb49660be9c2f81920e7d2d1a70b011fde17 Mon Sep 17 00:00:00 2001 From: WintersMontagne10335 <22251099@zju.edu.cn> Date: Fri, 15 Mar 2024 14:46:59 +0000 Subject: [PATCH 2/8] add test cases --- .../cinn/symbolic/test_op_infer_sym_shape.py | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/test/ir/pir/cinn/symbolic/test_op_infer_sym_shape.py b/test/ir/pir/cinn/symbolic/test_op_infer_sym_shape.py index 3a059d040357bc..1264d080d41f30 100644 --- a/test/ir/pir/cinn/symbolic/test_op_infer_sym_shape.py +++ b/test/ir/pir/cinn/symbolic/test_op_infer_sym_shape.py @@ -357,6 +357,73 @@ def test_eval_symbolic(self): return True +class MeshgridNet(paddle.nn.Layer): + def __init__(self): + super().__init__() + + def forward(self, x, y): + out_x, out_y = paddle.meshgrid(x, y) + return out_x, out_y + + +class TestMeshgridOpInferSymbolicShape(TestBase): + def prepare_data(self): + self.x_cases = [np.random.rand(1), np.random.rand(10), np.random.rand(100), np.random.rand(1000)] + self.y_cases = [np.random.rand(1), np.random.rand(10), np.random.rand(1000), np.random.rand(100)] + + self.expected = [ + [ + 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', + ], + [ + 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', + ], + [ + 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', + ], + [ + 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', + ], + ] + + def test_eval_symbolic(self): + net = MeshgridNet() + + for i in range(len(self.x_cases)): + x = self.x_cases[i] + y = self.y_cases[i] + x_spec = InputSpec( + shape=[None for index in range(len(x.shape))], dtype='float32' + ) + y_spec = InputSpec( + shape=[None for index in range(len(y.shape))], dtype='float32' + ) + + input_spec = [x_spec, y_spec] + net = apply_to_static(net, False, input_spec) + net.eval() + + # check the infer result + sym_shape_str_list = get_sym_shape_str_for_op( + net, input_spec, 'pd_op.meshgrid' + ) + np.testing.assert_equal( + len(sym_shape_str_list), len(self.expected[i]) + ) + for j in range(len(sym_shape_str_list)): + np.testing.assert_equal( + sym_shape_str_list[j].find(self.expected[i][j]), + 0, + f'in case i,j = {i},{j}: output shape ({sym_shape_str_list[j]}) is not expected {(self.expected[i][j])}', + ) + + # TODO(WintersMontagne10335): Add builtin.meshgrid op infer symbolic shape test + # Not added because attribute `sym_shape_str` does not support multi-output op now. + # See also: paddle/fluid/pir/transforms/shape_optimization_pass.cc:144. + + return True + + class TakeAlongAxisNet(paddle.nn.Layer): def __init__(self): super().__init__() From 87e0f7ba30d01476e28c3f70b05ad8561d313037 Mon Sep 17 00:00:00 2001 From: WintersMontagne10335 <22251099@zju.edu.cn> Date: Fri, 15 Mar 2024 15:13:43 +0000 Subject: [PATCH 3/8] resolve conflicts --- .../multiary_infer_sym.cc | 33 + .../infer_symbolic_shape/multiary_infer_sym.h | 1 + .../paddle_op_infer_sym.cc | 1211 ----------------- .../paddle_op_infer_sym.h | 74 - .../test_infer_sym_shape_multinary_op.py | 67 + .../cinn/symbolic/test_op_infer_sym_shape.py | 792 ----------- 6 files changed, 101 insertions(+), 2077 deletions(-) delete mode 100644 paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.cc delete mode 100644 paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.h delete mode 100644 test/ir/pir/cinn/symbolic/test_op_infer_sym_shape.py diff --git a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc index 4915d8b0ececaa..b4d73cd6426bb9 100644 --- a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc +++ b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc @@ -121,6 +121,39 @@ bool LogspaceOpInferSymbolicShape( return true; } +bool MeshgridOpInferSymbolicShape(pir::Operation *op, + pir::ShapeConstraintIRAnalysis *shape_analysis) { + const auto &attributes = op->attributes(); + const symbol::TensorListShapeOrDataDimExprs &shape_data_list = + shape_analysis->GetShapeOrDataForValue(op->operand_source(0)) + .dyn_cast(); + + const symbol::ShapeOrDataDimExprs sym_shape_dim_exprs = [&] { + symbol::TensorListShapeOrDataDimExprs shape_dim_exprs_list; + std::vector vec; + + for(auto& shape_data : shape_data_list){ + if(shape_data.shape().size()==0){ + vec.emplace_back(1); + }else{ + vec.emplace_back(shape_data.shape()[0]); + } + } + + auto shape_dim_exprs=symbol::TensorShapeOrDataDimExprs(vec); + + for(auto& shape_data : shape_data_list){ + shape_dim_exprs_list.emplace_back(shape_dim_exprs); + } + + return symbol::ShapeOrDataDimExprs(shape_dim_exprs_list); + }(); + + pir::Value res = op->result(0); + shape_analysis->SetShapeOrDataForValue(res, sym_shape_dim_exprs); + return true; +} + bool StackOpInferSymbolicShape(pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { pir::Value operand_source = op->operand_source(0); diff --git a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.h b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.h index a9ab30b20564af..34eb161c026896 100644 --- a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.h +++ b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.h @@ -22,6 +22,7 @@ OP_DECLARE_INFER_SYMBOLIC_SHAPE(Concat) OP_DECLARE_INFER_SYMBOLIC_SHAPE(FullWithTensor) OP_DECLARE_INFER_SYMBOLIC_SHAPE(Linspace) OP_DECLARE_INFER_SYMBOLIC_SHAPE(Logspace) +OP_DECLARE_INFER_SYMBOLIC_SHAPE(Meshgrid) OP_DECLARE_INFER_SYMBOLIC_SHAPE(Stack) OP_DECLARE_INFER_SYMBOLIC_SHAPE(Where) OP_DECLARE_INFER_SYMBOLIC_SHAPE(Where_) diff --git a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.cc b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.cc deleted file mode 100644 index 6bbf5a55682c92..00000000000000 --- a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.cc +++ /dev/null @@ -1,1211 +0,0 @@ -// Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.h" -#include "paddle/common/ddim.h" -#include "paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/infer_sym_slice_utils.h" -#include "paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/infer_sym_utils.h" -#include "paddle/fluid/pir/dialect/operator/ir/op_attribute.h" - -namespace paddle::dialect { - -bool DataOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - const auto &attributes = op->attributes(); - pir::Attribute attr = attributes.at("shape"); - - const std::vector sym_dims = [&] { - std::vector sym_dims; - const std::vector &dims = - attr.dyn_cast().data().GetData(); - for (auto dim : dims) { - symbol::DimExpr dim_expr; - if (dim == pir::ShapedTypeInterface::kDynamic) { - symbol::DimExpr symbolic_dim_expr(shape_analysis->GetNextSymName()); - dim_expr = symbolic_dim_expr; - } else { - symbol::DimExpr numeric_dim_expr(dim); - dim_expr = numeric_dim_expr; - } - sym_dims.push_back(dim_expr); - } - return sym_dims; - }(); - - symbol::ShapeOrDataDimExprs shape_data{ - symbol::TensorShapeOrDataDimExprs(sym_dims)}; - - shape_analysis->SetShapeOrDataForValue(op->result(0), shape_data); - - return true; -} - -bool ShapeOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - const symbol::ShapeOrDataDimExprs &operand_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)); - const auto &out_data = operand_shape_or_data.shape(); - const std::vector shape{std::int64_t(out_data.size())}; - symbol::ShapeOrDataDimExprs shape_or_data{ - symbol::TensorShapeOrDataDimExprs(shape, out_data)}; - - shape_analysis->SetShapeOrDataForValue(op->result(0), shape_or_data); - return true; -} - -bool ShapeSrOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - return ShapeOpInferSymbolicShape(op, shape_analysis); -} - -bool StackOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - pir::Value operand_source = op->operand_source(0); - - const auto &attributes = op->attributes(); - int axis = attributes.at("axis").dyn_cast().data(); - - const symbol::TensorListShapeOrDataDimExprs &shape_data_list = - shape_analysis->GetShapeOrDataForValue(operand_source) - .dyn_cast(); - - int rank = shape_data_list[0].shape().size(); - if (axis < 0) axis += rank + 1; - - const symbol::ShapeOrDataDimExprs shape_data = [&] { - std::vector shape_dim_exprs; - std::vector data_dim_exprs; - for (size_t i = 0; i < shape_data_list.size(); ++i) { - if (shape_data_list[i].data().has_value() && axis == 0) { - data_dim_exprs.emplace_back(shape_data_list[i].data().value()[0]); - } - } - - if (!data_dim_exprs.empty()) { - shape_dim_exprs.emplace_back( - static_cast(shape_data_list.size())); - } else { - for (int i = 0; i < rank; ++i) { - details::BuildCstrEqForTensorListAlongAxis( - shape_analysis, shape_data_list, i); - } - shape_dim_exprs.insert(shape_dim_exprs.begin() + axis, - static_cast(shape_data_list.size())); - } - - return symbol::ShapeOrDataDimExprs( - symbol::TensorShapeOrDataDimExprs(shape_dim_exprs, data_dim_exprs)); - }(); - - pir::Value res = op->result(0); - shape_analysis->SetShapeOrDataForValue(res, shape_data); - return true; -} - -bool SumOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - bool keepdim = GetBoolAttr(op, "keepdim"); - bool reduce_all = false; - - auto axis_gen_op = op->operand_source(1).defining_op(); - if (axis_gen_op->isa()) { - std::vector axis = details::GetVectorAttr( - axis_gen_op->dyn_cast(), "value"); - if (axis.size() == 0) { - reduce_all = true; - } - return details::ReduceInferDim( - op, shape_analysis, axis, keepdim, reduce_all); - } else { - // TODO(lanxianghit): deal with other source: pir::VectorType, - // paddle::dialect::DenseTensorType - PADDLE_THROW( - phi::errors::Unimplemented("SumOpInferSymbolicShape: 'axis' only " - "support FullIntArrayOp's result now.")); - } - - return true; -} - -bool ProdOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - bool keepdim = GetBoolAttr(op, "keep_dim"); - bool reduce_all = GetBoolAttr(op, "reduce_all"); - - auto axis_gen_op = op->operand_source(1).defining_op(); - if (axis_gen_op->isa()) { - std::vector axis = details::GetVectorAttr( - axis_gen_op->dyn_cast(), "value"); - return details::ReduceInferDim( - op, shape_analysis, axis, keepdim, reduce_all); - } else { - // TODO(lanxianghit): deal with other source: pir::VectorType, - // paddle::dialect::DenseTensorType - PADDLE_THROW( - phi::errors::Unimplemented("ProdOpInferSymbolicShape: 'axis' only " - "support FullIntArrayOp's result now.")); - } - - return true; -} - -bool FullIntArrayOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - const auto &attributes = op->attributes(); - pir::Attribute attr_value = attributes.at("value"); - const auto &vec = attr_value.dyn_cast().AsVector(); - - const std::vector data = [&] { - std::vector data; - for (auto item : vec) { - int64_t i = item.dyn_cast().data(); - data.push_back(symbol::DimExpr(i)); - } - return data; - }(); - - const std::vector shape{std::int64_t(vec.size())}; - - symbol::ShapeOrDataDimExprs shape_data{ - symbol::TensorShapeOrDataDimExprs(shape, data)}; - - pir::Value res = op->result(0); - shape_analysis->SetShapeOrDataForValue(res, shape_data); - return true; -} - -bool SliceOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - pir::Value operand_source = op->operand_source(0); - pir::Value operand_starts = op->operand_source(1); - pir::Value operand_ends = op->operand_source(2); - pir::Value res = op->result(0); - - const symbol::ShapeOrDataDimExprs &operand_shape_or_data = - shape_analysis->GetShapeOrDataForValue(operand_source); - const symbol::ShapeOrDataDimExprs &starts_shape_data = - shape_analysis->GetShapeOrDataForValue(operand_starts); - const symbol::ShapeOrDataDimExprs &ends_shape_data = - shape_analysis->GetShapeOrDataForValue(operand_ends); - - std::vector axes_vec = details::GetVectorAttr(op, "axes"); - - // // Currently, we DO NOT support any element in `starts` is a Symbol. - ExprVec starts = slice_utils::GetExprVecFromData(starts_shape_data); - ExprVec ends = slice_utils::GetExprVecFromData(ends_shape_data); - - std::vector infer_flags = details::GetVectorAttr(op, "infer_flags"); - - const std::vector decrease_axis = - details::GetVectorAttr(op, "decrease_axis"); - - shape_analysis->SetShapeOrDataForValue( - res, - slice_utils::SliceRawInferSymbolicShape(operand_shape_or_data, - starts, - ends, - axes_vec, - infer_flags, - decrease_axis)); - - return true; -} - -bool FullOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - const auto &attributes = op->attributes(); - - const std::vector shape = [&] { - pir::Attribute attr_shape = attributes.at("shape"); - const auto &shape_vec = - attr_shape.dyn_cast() - .data() - .GetData(); - std::vector shape(shape_vec.begin(), shape_vec.end()); - return shape; - }(); - - const auto shape_data = [&]() -> symbol::TensorShapeOrDataDimExprs { - // NOTE(Aurelius84): to is a risky operation when Scalar's dtype is - // not int32/int64. However, we found Full's Value could be like '3.0' but - // used as int. - const int64_t value = attributes.at("value") - .dyn_cast() - .data() - .to(); - const size_t shape_size = shape.size(); - // NOTE(Aurelius84): When shape.size()==1, a new std::vector with - // length = shape[0] will be constructed, but not all cases are used for - // ShapeAnalysis. Considering MAX_RANK < 9 in Paddle, we limit it below - // DATA_MAX_LENGTH = 128 and will not create this vector once length > - // DATA_MAX_LENGTH. - constexpr int64_t DATA_MAX_LENGTH = 128; - if (shape_size == 0U) { - std::vector data{value}; - return symbol::TensorShapeOrDataDimExprs(shape, data); - } else if (shape_size == 1U && - shape[0].template Get() <= DATA_MAX_LENGTH) { - std::vector data(shape[0].template Get(), - symbol::DimExpr(value)); - return symbol::TensorShapeOrDataDimExprs(shape, data); - } else { - return symbol::TensorShapeOrDataDimExprs(shape); - } - }(); - - shape_analysis->SetShapeOrDataForValue( - op->result(0), symbol::ShapeOrDataDimExprs(shape_data)); - return true; -} - -bool ConcatOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - pir::Value operand_source = op->operand_source(0); - const auto &shape_data_list = - shape_analysis->GetShapeOrDataForValue(operand_source) - .dyn_cast(); - - CHECK(op->operand_source(1).defining_op()->isa()); - - int64_t axis = op->operand_source(1) - .defining_op() - .attributes() - .at("value") - .dyn_cast() - .data() - .to(); - size_t rank = shape_data_list[0].shape().size(); - axis = axis >= 0 ? axis : std::max(int64_t(0), int64_t(axis + rank)); - - if (shape_data_list[0].data().has_value()) { - if (rank == 1) { - ExprVec data = details::GetExprVecFromData( - shape_analysis->GetShapeOrDataForValue(operand_source)); - const std::vector shape{std::int64_t(data.size())}; - symbol::ShapeOrDataDimExprs shape_data{ - symbol::TensorShapeOrDataDimExprs(shape, data)}; - pir::Value res = op->result(0); - shape_analysis->SetShapeOrDataForValue(res, shape_data); - - return true; - } else { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + - " 's InferSymbolicShape can NOT deal with rank > 1 now.")); - } - std::vector data; - data.reserve(shape_data_list.size()); - for (auto &data_elem : shape_data_list) { - data.push_back(data_elem.data().value()[0]); - } - const std::vector shape{std::int64_t(data.size())}; - symbol::ShapeOrDataDimExprs shape_data{ - symbol::TensorShapeOrDataDimExprs(shape, data)}; - pir::Value res = op->result(0); - shape_analysis->SetShapeOrDataForValue(res, shape_data); - - return true; - } - - const std::vector &out_dims = [&] { - std::vector out_dims = shape_data_list[0].shape(); - for (size_t i = 0; i < rank; ++i) { - if (i != static_cast(axis)) { - details::BuildCstrEqForTensorListAlongAxis( - shape_analysis, shape_data_list, i); - continue; - } - for (size_t j = 1; j < shape_data_list.size(); ++j) { - out_dims[axis] = out_dims[axis] + shape_data_list[j].shape()[axis]; - } - } - return out_dims; - }(); - - symbol::ShapeOrDataDimExprs shape_data{ - symbol::TensorShapeOrDataDimExprs(out_dims)}; - - pir::Value res = op->result(0); - shape_analysis->SetShapeOrDataForValue(res, shape_data); - - return true; -} - -bool GatherNdOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - const auto &x_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)); - const auto &index_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(1)); - - const std::vector &x_sym_shape = - x_shape_or_data.data().has_value() ? x_shape_or_data.data().value() - : x_shape_or_data.shape(); - - const std::vector &index_sym_shape = - index_shape_or_data.data().has_value() - ? index_shape_or_data.data().value() - : index_shape_or_data.shape(); - - int x_dims_size = x_sym_shape.size(); - int index_dims_size = index_sym_shape.size(); - - std::vector result_sym_dims; - // The result dims is - // Index.shape[:-1] + X.shape[Index.shape[-1]:] - for (int i = 0; i < index_dims_size - 1; ++i) { - result_sym_dims.emplace_back(index_sym_shape[i]); - } - - PADDLE_ENFORCE_EQ( - index_sym_shape[index_dims_size - 1].Has(), - true, - phi::errors::InvalidArgument( - "in GatherNdOpInferSymbolicShape: index[-1] should be unknown")); - - for (int i = static_cast( - index_sym_shape[index_dims_size - 1].Get()); - i < x_dims_size; - ++i) { - result_sym_dims.emplace_back(x_sym_shape[i]); - } - - symbol::ShapeOrDataDimExprs shape_data{ - symbol::TensorShapeOrDataDimExprs(result_sym_dims)}; - - pir::Value res = op->result(0); - shape_analysis->SetShapeOrDataForValue(res, shape_data); - - return true; -} - -bool TileOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - pir::Value operand_x = op->operand_source(0); - symbol::ShapeOrDataDimExprs x_shape_or_data = - shape_analysis->GetShapeOrDataForValue(operand_x); - pir::Value operand_repeat_times = op->operand_source(1); - symbol::ShapeOrDataDimExprs repeat_times_shape_or_data = - shape_analysis->GetShapeOrDataForValue(operand_repeat_times); - - std::vector x_dimexpr; - if (x_shape_or_data.data().has_value()) { - x_dimexpr = x_shape_or_data.data().value(); - } else { - x_dimexpr = x_shape_or_data.shape(); - } - - std::vector repeat_times_dimexpr; - if (repeat_times_shape_or_data.data().has_value()) { - repeat_times_dimexpr = repeat_times_shape_or_data.data().value(); - } else { - repeat_times_dimexpr = repeat_times_shape_or_data.shape(); - } - if (repeat_times_dimexpr.empty()) { - repeat_times_dimexpr = std::vector(x_dimexpr.size(), 1); - } - - auto out_rank = std::max(static_cast(x_dimexpr.size()), - repeat_times_dimexpr.size()); - std::vector out_shape(out_rank); - if (x_dimexpr.size() > repeat_times_dimexpr.size()) { - auto diff = x_dimexpr.size() - repeat_times_dimexpr.size(); - repeat_times_dimexpr.insert(repeat_times_dimexpr.begin(), diff, 1); - } else { - auto diff = repeat_times_dimexpr.size() - x_dimexpr.size(); - x_dimexpr.insert(x_dimexpr.begin(), diff, 1); - } - - for (size_t i = 0; i < repeat_times_dimexpr.size(); ++i) { - out_shape[i] = x_dimexpr[i] * repeat_times_dimexpr[i]; - } - - symbol::ShapeOrDataDimExprs shape_data{ - symbol::TensorShapeOrDataDimExprs(out_shape)}; - - pir::Value res = op->result(0); - shape_analysis->SetShapeOrDataForValue(res, shape_data); - - return true; -} - -bool TransposeOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - std::vector perm = - op->attributes().at("perm").dyn_cast().AsVector(); - if (perm.size() == 1) { - // perm must be [0], which means nothing to do with input, just copy the - // info from input - shape_analysis->SetShapeOrDataForValue( - op->result(0), - shape_analysis->GetShapeOrDataForValue(op->operand_source(0))); - return true; - } - const std::vector &x_dims = [&] { - std::vector dims; - const auto &x_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)); - if (x_shape_or_data.data().has_value()) { - dims = x_shape_or_data.data().value(); - } else { - dims = x_shape_or_data.shape(); - } - return dims; - }(); - - int x_rank = x_dims.size(); - - const std::vector formatted_axis = [op, x_rank, &perm] { - std::vector out(perm.size(), 0); - std::transform(perm.begin(), - perm.end(), - out.begin(), - [](pir::Attribute &p) -> int32_t { - return p.dyn_cast().data(); - }); - - // format the negative axis - std::for_each(out.begin(), out.end(), [x_rank](int32_t &v) { - if (v < 0) { - v += x_rank; - } - }); - return out; - }(); - - int axis_size = static_cast(formatted_axis.size()); - - std::vector out_dims(x_dims); - for (int i = 0; i < axis_size; ++i) { - out_dims[i] = x_dims[formatted_axis[i]]; - } - - shape_analysis->SetShapeOrDataForValue(op->result(0), - ShapeOrData{TensorExprs(out_dims)}); - - return true; -} -bool Transpose_OpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - return TransposeOpInferSymbolicShape(op, shape_analysis); -} - -bool ArangeOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - const auto &start_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)); - const auto &end_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(1)); - const auto &step_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(2)); - - const auto start = [&] { - symbol::DimExpr expr; - if (start_shape_or_data.data().has_value()) { - expr = start_shape_or_data.data().value()[0]; - } else { - expr = start_shape_or_data.shape()[0]; - } - return expr; - }(); - - const auto end = [&] { - symbol::DimExpr expr; - if (end_shape_or_data.data().has_value()) { - expr = end_shape_or_data.data().value()[0]; - } else { - expr = end_shape_or_data.shape()[0]; - } - return expr; - }(); - - const auto step = [&] { - symbol::DimExpr expr; - if (step_shape_or_data.data().has_value()) { - expr = step_shape_or_data.data().value()[0]; - } else { - expr = step_shape_or_data.shape()[0]; - } - return expr; - }(); - - const symbol::ShapeOrDataDimExprs &shape_data = [&] { - std::vector out_dims; - // TODO(lanxianghit, jiahy0825): here should be ceil((end - start) / step), - // but DimExpr doesn't support ceil and float now - out_dims.emplace_back((end - start) / step); - return symbol::ShapeOrDataDimExprs{ - symbol::TensorShapeOrDataDimExprs(out_dims)}; - }(); - - shape_analysis->SetShapeOrDataForValue(op->result(0), shape_data); - - return true; -} - -bool EmbeddingOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - const auto x_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)); - const auto weight_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(1)); - const std::vector &x_dims = [&] { - std::vector dims; - if (x_shape_or_data.data().has_value()) { - dims = x_shape_or_data.data().value(); - } else { - dims = x_shape_or_data.shape(); - } - return dims; - }(); - - const std::vector &weight_dims = [&] { - std::vector dims; - if (weight_shape_or_data.data().has_value()) { - dims = weight_shape_or_data.data().value(); - } else { - dims = weight_shape_or_data.shape(); - } - return dims; - }(); - - const symbol::ShapeOrDataDimExprs &shape_data = [&] { - std::vector out_dims = x_dims; - // no need to check validation of weight_dims index, since all checks have - // been done at corresponding InferMeta - out_dims.emplace_back(weight_dims[1]); - return symbol::ShapeOrDataDimExprs{ - symbol::TensorShapeOrDataDimExprs(out_dims)}; - }(); - - shape_analysis->SetShapeOrDataForValue(op->result(0), shape_data); - - return true; -} - -bool SparseWeightEmbeddingOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} - -bool MatmulOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - // x_dims can't be const or ref here, in case to be broadcasted - std::vector x_dims = [&] { - std::vector dims; - const auto &x_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)); - if (x_shape_or_data.data().has_value()) { - dims = x_shape_or_data.data().value(); - } else { - dims = x_shape_or_data.shape(); - } - return dims; - }(); - - // y_dims can't be const or ref here, in case to be broadcasted - std::vector y_dims = [&] { - std::vector dims; - const auto y_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(1)); - if (y_shape_or_data.data().has_value()) { - dims = y_shape_or_data.data().value(); - } else { - dims = y_shape_or_data.shape(); - } - return dims; - }(); - - size_t ndims_x = x_dims.size(); - size_t ndims_y = y_dims.size(); - - const bool x_broadcasted = [&] { - bool broadcasted = false; - if (ndims_x == 1) { - x_dims.insert(x_dims.begin(), 1); - ndims_x = 2; - broadcasted = true; - } - return broadcasted; - }(); - - const bool y_broadcasted = [&] { - bool broadcasted = false; - if (ndims_y == 1) { - y_dims.emplace_back(1); - ndims_y = 2; - broadcasted = true; - } - return broadcasted; - }(); - - std::vector out_dims; - if (ndims_x > ndims_y) { - out_dims.assign(x_dims.begin(), x_dims.end() - 2); - } else if (ndims_x < ndims_y) { - out_dims.assign(y_dims.begin(), y_dims.end() - 2); - } else { - symbol::DimExprBuilder builder{nullptr}; - for (size_t i = 0; i < ndims_x - 2; ++i) { - out_dims.emplace_back(builder.Broadcast(x_dims[i], y_dims[i])); - } - } - - bool transpose_x_attr = GetBoolAttr(op, "transpose_x"); - bool transpose_y_attr = GetBoolAttr(op, "transpose_y"); - symbol::DimExpr out_M = - transpose_x_attr ? x_dims[ndims_x - 1] : x_dims[ndims_x - 2]; - symbol::DimExpr out_N = - transpose_y_attr ? y_dims[ndims_y - 2] : y_dims[ndims_y - 1]; - if (!x_broadcasted) { - out_dims.emplace_back(out_M); - } - if (!y_broadcasted) { - out_dims.emplace_back(out_N); - } - - shape_analysis->SetShapeOrDataForValue(op->result(0), - ShapeOrData{TensorExprs(out_dims)}); - - if ((ndims_x == ndims_y) && ndims_x >= 2) { - if (transpose_x_attr == false && transpose_y_attr == false) { - shape_analysis->CreateDimExprBuilder().CstrEq(x_dims[ndims_x - 1], - y_dims[ndims_x - 2]); - } else if (transpose_x_attr == false && transpose_y_attr == true) { - shape_analysis->CreateDimExprBuilder().CstrEq(x_dims[ndims_x - 1], - y_dims[ndims_x - 1]); - } else if (transpose_x_attr == true && transpose_y_attr == false) { - shape_analysis->CreateDimExprBuilder().CstrEq(x_dims[ndims_x - 2], - y_dims[ndims_x - 2]); - } else { - shape_analysis->CreateDimExprBuilder().CstrEq(x_dims[ndims_x - 2], - y_dims[ndims_x - 1]); - } - - for (size_t i = 0; i < ndims_x - 2; ++i) { - shape_analysis->CreateDimExprBuilder().CstrEq(x_dims[i], y_dims[i]); - } - } - return true; -} - -bool MaxOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - bool keepdim = GetBoolAttr(op, "keepdim"); - - const std::vector axis = [&] { - pir::Operation *axis_gen_op = op->operand_source(1).defining_op(); - std::vector axis_vec; - if (axis_gen_op->isa()) { - axis_vec = details::GetVectorAttr( - axis_gen_op->dyn_cast(), "value"); - } else { - // TODO(lanxianghit): there's other source: pir::VectorType, - // paddle::dialect::DenseTensorType, but after PRIM, maybe always - // FullIntArrayOp, to be confirmed - PADDLE_THROW( - phi::errors::Unimplemented("MaxOpInferSymbolicShape: 'axis' only " - "support FullIntArrayOp's result now.")); - } - return axis_vec; - }(); - - bool reduce_all = axis.size() == 0 ? true : false; - - return details::ReduceInferDim(op, shape_analysis, axis, keepdim, reduce_all); -} - -bool WhereOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - shape_analysis->SetShapeOrDataForValue( - op->result(0), - shape_analysis->GetShapeOrDataForValue(op->operand_source(0))); - - const std::vector &operands = {op->operand_source(0), - op->operand_source(1)}; - - size_t rank = shape_analysis->GetShapeOrDataForValue(op->operand_source(0)) - .shape() - .size(); - - for (size_t i = 0; i < rank; ++i) { - paddle::dialect::details::BuildCstrEqForTensorListAlongAxis( - shape_analysis, operands, i); - } - - return true; -} - -bool Where_OpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - return WhereOpInferSymbolicShape(op, shape_analysis); -} - -bool FeedOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - const common::DDim &result_dims = - op->result(0).type().dyn_cast().dims(); - std::vector out_dims; - for (int i = 0; i < result_dims.size(); i++) { - if (result_dims[i] == -1) { - out_dims.emplace_back(shape_analysis->GetNextSymName()); - } else { - out_dims.emplace_back(result_dims[i]); - } - } - - shape_analysis->SetShapeOrDataForValue( - op->result(0), - symbol::ShapeOrDataDimExprs{symbol::TensorShapeOrDataDimExprs(out_dims)}); - - return true; -} - -bool TopPSamplingOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - const auto &x_dims = [op, shape_analysis] { - const auto &shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)); - if (shape_or_data.data().has_value()) { - return shape_or_data.data().value(); - } else { - return shape_or_data.shape(); - } - }(); - - // all the result have the same shape - for (uint32_t rst_idx = 0; rst_idx < op->num_results(); rst_idx++) { - const std::vector out_dims{x_dims[0], 1}; - shape_analysis->SetShapeOrDataForValue( - op->result(rst_idx), - symbol::ShapeOrDataDimExprs{ - symbol::TensorShapeOrDataDimExprs(out_dims)}); - } - - return true; -} - -bool ExpandAsOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} - -bool MeshgridOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - const auto &attributes = op->attributes(); - const symbol::TensorListShapeOrDataDimExprs &shape_data_list = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)) - .dyn_cast(); - - const symbol::ShapeOrDataDimExprs sym_shape_dim_exprs = [&] { - symbol::TensorListShapeOrDataDimExprs shape_dim_exprs_list; - std::vector vec; - - for(auto& shape_data : shape_data_list){ - if(shape_data.shape().size()==0){ - vec.emplace_back(1); - }else{ - vec.emplace_back(shape_data.shape()[0]); - } - } - - auto shape_dim_exprs=symbol::TensorShapeOrDataDimExprs(vec); - - for(auto& shape_data : shape_data_list){ - shape_dim_exprs_list.emplace_back(shape_dim_exprs); - } - - return symbol::ShapeOrDataDimExprs(shape_dim_exprs_list); - }(); - - pir::Value res = op->result(0); - shape_analysis->SetShapeOrDataForValue(res, sym_shape_dim_exprs); - return true; -} - -bool SplitOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - // input - const auto &x_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)); - PADDLE_ENFORCE_EQ(x_shape_or_data.data().has_value(), - false, - phi::errors::InvalidArgument( - "InferSymbolicShape of SplitOp only support input with " - "value now.")); - const auto &x_dims_sym = x_shape_or_data.shape(); - - // axis - CHECK(op->operand_source(2).defining_op()->isa()); - - int64_t axis = op->operand_source(2) - .defining_op() - .attributes() - .at("value") - .dyn_cast() - .data() - .to(); - - // sections - const std::vector §ions_sym = [&] { - const auto §ions_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(1)); - std::vector sections_sym; - if (sections_shape_or_data.data().has_value()) { - sections_sym = sections_shape_or_data.data().value(); - } else { - sections_sym = sections_shape_or_data.shape(); - } - return sections_sym; - }(); - - // output - const symbol::TensorListShapeOrDataDimExprs &output_shape_data_list = [&] { - const auto &GetSum = [&](const auto &dim_exprs, const auto &Filter) { - symbol::DimExpr sum{0}; - for (const auto &dim_expr : dim_exprs) { - if (Filter(dim_expr)) { - sum = sum + dim_expr; - } - } - return sum; - }; - const auto &All = [&](const auto &dim_exprs, const auto &Cond) { - for (const auto &dim_expr : dim_exprs) { - if (!Cond(dim_expr)) { - return false; - } - } - return true; - }; - const auto &IsNotMinusOne = [&](const symbol::DimExpr &dim_expr) { - if (dim_expr.isa()) { - return dim_expr.dyn_cast() != static_cast(-1); - } - return true; - }; - const auto &sum_exclude_minus_one = GetSum(sections_sym, IsNotMinusOne); - - const bool &all_sections_sym_not_minus_one = - All(sections_sym, IsNotMinusOne); - if (all_sections_sym_not_minus_one) { - shape_analysis->CreateDimExprBuilder().CstrEq(x_dims_sym[axis], - sum_exclude_minus_one); - } - - symbol::TensorListShapeOrDataDimExprs shape_data_list; - std::vector output_dims_sym = x_dims_sym; - if (!all_sections_sym_not_minus_one && sections_sym.size() == 1) { - VLOG(3) << "[SplitOp]-1 is the only split section. The output shape is " - "identical to the input shape."; - shape_data_list.push_back( - symbol::TensorShapeOrDataDimExprs(output_dims_sym)); - return shape_data_list; - } - for (uint32_t idx = 0; idx < sections_sym.size(); idx++) { - const auto §ion_sym = sections_sym[idx]; - output_dims_sym[axis] = IsNotMinusOne(section_sym) - ? section_sym - : x_dims_sym[axis] - sum_exclude_minus_one; - - shape_data_list.push_back( - symbol::TensorShapeOrDataDimExprs(output_dims_sym)); - } - return shape_data_list; - }(); - - shape_analysis->SetShapeOrDataForValue( - op->result(0), symbol::ShapeOrDataDimExprs{output_shape_data_list}); - - return true; -} - -// Not Implemented Ops. -bool GatherOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - const auto &input_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)); - const auto &index_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(1)); - - const auto &numel = [&] { - symbol::DimExpr numel{1}; - for (const auto &dim_expr : index_shape_or_data.shape()) { - numel = numel * dim_expr; - } - return numel; - }(); - - const auto &axis_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(2)); - - const std::vector &input_sym_shape = - input_shape_or_data.data().has_value() - ? input_shape_or_data.data().value() - : input_shape_or_data.shape(); - - const std::vector &index_sym_shape = - index_shape_or_data.data().has_value() - ? index_shape_or_data.data().value() - : index_shape_or_data.shape(); - - int axis = - static_cast(axis_shape_or_data.data().value()[0].Get()); - if (axis < 0) axis += input_sym_shape.size(); - - const auto &out_sym_shape = [&] { - std::vector out_sym_shape; - - if (index_sym_shape.size() == 0) { - if (input_sym_shape.size() == 1) { - out_sym_shape.push_back(symbol::DimExpr{0}); - } else { - for (int i = 0; i < axis; ++i) { - out_sym_shape.push_back(input_sym_shape[i]); - } - for (size_t i = axis + 1; i < input_sym_shape.size(); ++i) { - out_sym_shape.push_back(input_sym_shape[i]); - } - } - } else { - for (int i = 0; i < axis; ++i) { - out_sym_shape.push_back(input_sym_shape[i]); - } - out_sym_shape.push_back(numel); - for (size_t i = axis + 1; i < input_sym_shape.size(); ++i) { - out_sym_shape.push_back(input_sym_shape[i]); - } - } - return out_sym_shape; - }(); - - symbol::ShapeOrDataDimExprs shape_data{ - symbol::TensorShapeOrDataDimExprs(out_sym_shape)}; - - pir::Value res = op->result(0); - shape_analysis->SetShapeOrDataForValue(res, shape_data); - - return true; -} - -bool KronOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - const auto &x_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)).shape(); - const auto &y_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(1)).shape(); - const int rank_x = x_shape_or_data.size(); - const int rank_y = y_shape_or_data.size(); - const int rank = (rank_x > rank_y) ? rank_x : rank_y; - - std::vector dim_out; - dim_out.reserve(rank); - const auto one = symbol::DimExpr{1}; - const auto minus_one = symbol::DimExpr{-1}; - for (int i = 0; i < rank; i++) { - symbol::DimExpr dim_xi = - (i < rank - rank_x) ? one : x_shape_or_data.at(i - (rank - rank_x)); - symbol::DimExpr dim_yi = - (i < rank - rank_y) ? one : y_shape_or_data.at(i - (rank - rank_y)); - dim_out.push_back(dim_xi * dim_yi); - } - symbol::ShapeOrDataDimExprs shape_data{ - symbol::TensorShapeOrDataDimExprs(dim_out)}; - pir::Value res = op->result(0); - shape_analysis->SetShapeOrDataForValue(res, shape_data); - return true; -} - -// Not Impelmented Ops. -bool LogcumsumexpOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} - -bool MaskedSelectOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool PoissonOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} - -bool SearchsortedOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} - -bool TakeAlongAxisOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - // input - const auto &arr_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(0)); - const auto &indices_shape_or_data = - shape_analysis->GetShapeOrDataForValue(op->operand_source(1)); - const auto &attributes = op->attributes(); - int axis = attributes.at("axis").dyn_cast().data(); - - const std::vector &arr_sym_shape = - arr_shape_or_data.data().has_value() ? arr_shape_or_data.data().value() - : arr_shape_or_data.shape(); - const std::vector &indices_sym_shape = - indices_shape_or_data.data().has_value() - ? indices_shape_or_data.data().value() - : indices_shape_or_data.shape(); - - if (axis < 0) axis += arr_sym_shape.size(); - - const auto &out_sym_shape = [&] { - std::vector out_sym_shape; - for (int i = 0; i < axis; ++i) { - out_sym_shape.push_back(arr_sym_shape[i]); - } - out_sym_shape.push_back(indices_sym_shape[axis]); - for (size_t i = axis + 1; i < arr_sym_shape.size(); ++i) { - out_sym_shape.push_back(arr_sym_shape[i]); - } - return out_sym_shape; - }(); - - symbol::ShapeOrDataDimExprs shape_data{ - symbol::TensorShapeOrDataDimExprs(out_sym_shape)}; - - pir::Value res = op->result(0); - shape_analysis->SetShapeOrDataForValue(res, shape_data); - - return true; -} - -bool TopkOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool UnbindOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool UniqueConsecutiveOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool LinspaceOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool LogspaceOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool LogsumexpOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} - -bool MinOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} - -bool PadOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool RandintOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} - -bool RepeatInterleaveOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool SplitWithNumOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool TrilIndicesOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool TriuIndicesOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool UniformOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} -bool UniqueOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - PADDLE_THROW(phi::errors::Unimplemented( - op->name() + " 's InferSymbolicShape interface is NOT implemented now.")); - return true; -} - -bool FullWithTensorOpInferSymbolicShape( - pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - pir::Value operand_source = op->operand_source(0); - const symbol::ShapeOrDataDimExprs &operand_shape_or_data = - shape_analysis->GetShapeOrDataForValue(operand_source); - - const auto &out_shape = operand_shape_or_data.data().has_value() - ? operand_shape_or_data.data().value() - : operand_shape_or_data.shape(); - - shape_analysis->SetShapeOrDataForValue( - op->result(0), symbol::TensorShapeOrDataDimExprs(out_shape)); - return true; -} -} // namespace paddle::dialect diff --git a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.h b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.h deleted file mode 100644 index d60a4f1640d14e..00000000000000 --- a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/paddle_op_infer_sym.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "paddle/pir/include/dialect/shape/utils/shape_analysis.h" - -namespace paddle::dialect { - -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Data) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Shape) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(ShapeSr) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Stack) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Sum) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(FullIntArray) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Slice) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Full) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Concat) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(GatherNd) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Tile) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Transpose) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Transpose_) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Prod) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(TakeAlongAxis) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Arange) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Embedding) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(SparseWeightEmbedding) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Matmul) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Max) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Meshgrid) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Where) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Where_) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Feed) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(TopPSampling) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(ExpandAs) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Split) - -// Not Impelmented Ops. - -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Gather) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Kron) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Logcumsumexp) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(MaskedSelect) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Poisson) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Searchsorted) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Topk) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Unbind) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(UniqueConsecutive) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Linspace) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Logspace) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Logsumexp) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Min) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Pad) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Randint) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(RepeatInterleave) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(SplitWithNum) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(TrilIndices) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(TriuIndices) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Uniform) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(Unique) -OP_DECLARE_INFER_SYMBOLIC_SHAPE(FullWithTensor) - -} // namespace paddle::dialect diff --git a/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py b/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py index 82272b4a0f59a9..9fca0f3a161372 100644 --- a/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py +++ b/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py @@ -62,6 +62,73 @@ def test_eval_symbolic(self): return out +class MeshgridNet(paddle.nn.Layer): + def __init__(self): + super().__init__() + + def forward(self, x, y): + out_x, out_y = paddle.meshgrid(x, y) + return out_x, out_y + + +class TestMeshgridOpInferSymbolicShape(TestBase): + def prepare_data(self): + self.x_cases = [np.random.rand(1), np.random.rand(10), np.random.rand(100), np.random.rand(1000)] + self.y_cases = [np.random.rand(1), np.random.rand(10), np.random.rand(1000), np.random.rand(100)] + + self.expected = [ + [ + 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', + ], + [ + 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', + ], + [ + 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', + ], + [ + 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', + ], + ] + + def test_eval_symbolic(self): + net = MeshgridNet() + + for i in range(len(self.x_cases)): + x = self.x_cases[i] + y = self.y_cases[i] + x_spec = InputSpec( + shape=[None for index in range(len(x.shape))], dtype='float32' + ) + y_spec = InputSpec( + shape=[None for index in range(len(y.shape))], dtype='float32' + ) + + input_spec = [x_spec, y_spec] + net = apply_to_static(net, False, input_spec) + net.eval() + + # check the infer result + sym_shape_str_list = get_sym_shape_str_for_op( + net, input_spec, 'pd_op.meshgrid' + ) + np.testing.assert_equal( + len(sym_shape_str_list), len(self.expected[i]) + ) + for j in range(len(sym_shape_str_list)): + np.testing.assert_equal( + sym_shape_str_list[j].find(self.expected[i][j]), + 0, + f'in case i,j = {i},{j}: output shape ({sym_shape_str_list[j]}) is not expected {(self.expected[i][j])}', + ) + + # TODO(WintersMontagne10335): Add builtin.meshgrid op infer symbolic shape test + # Not added because attribute `sym_shape_str` does not support multi-output op now. + # See also: paddle/fluid/pir/transforms/shape_optimization_pass.cc:144. + + return True + + class SliceNet(paddle.nn.Layer): def __init__(self): super().__init__() diff --git a/test/ir/pir/cinn/symbolic/test_op_infer_sym_shape.py b/test/ir/pir/cinn/symbolic/test_op_infer_sym_shape.py deleted file mode 100644 index 1264d080d41f30..00000000000000 --- a/test/ir/pir/cinn/symbolic/test_op_infer_sym_shape.py +++ /dev/null @@ -1,792 +0,0 @@ -# Copyright (c) 2024 PaddlePaddle Authors. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import unittest - -import numpy as np - -import paddle -from paddle.static import InputSpec - - -def get_sym_shape_str_for_op(net, input_spec, op_name='builtin.shadow_output'): - forward_program = net.forward.get_concrete_program(*input_spec)[ - 1 - ].infer_program.forward_program - all_sym_shape_str = [] - for op in forward_program.global_block().ops: - if op.name() == op_name: - all_sym_shape_str.append(op.attrs()['sym_shape_str']) - - return all_sym_shape_str - - -def apply_to_static(net, use_cinn, input_spec=None): - build_strategy = paddle.static.BuildStrategy() - build_strategy.build_cinn_pass = use_cinn - return paddle.jit.to_static( - net, - input_spec=input_spec, - build_strategy=build_strategy, - full_graph=True, - ) - - -class TestBase(unittest.TestCase): - def setUp(self): - paddle.seed(2022) - self.prepare_data() - - def prepare_data(self): - pass - - def test_eval_symbolic(self): - pass - - -class EmbeddingNet(paddle.nn.Layer): - def __init__(self, num_embeddings, embedding_dim): - super().__init__() - self.embedding = paddle.nn.Embedding( - num_embeddings, - embedding_dim, - weight_attr=paddle.ParamAttr( - initializer=paddle.nn.initializer.XavierNormal() - ), - ) - - def forward(self, x): - out = self.embedding(x) - - return out - - -class TestEmbeddingOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.x_shape = [1, 2048] - self.num_embeddings = 32000 - self.embedding_dim = 768 - self.x = paddle.randint(low=0, high=768, shape=self.x_shape) - self.expected_sym_shape = 'shape[S0, S1, 768], data[NULL]' - - def test_eval_symbolic(self): - net = EmbeddingNet(self.num_embeddings, self.embedding_dim) - input_spec = [ - InputSpec(shape=[None, None], dtype='float32'), - ] - net = apply_to_static(net, False, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'builtin.shadow_output' - ) - np.testing.assert_equal(len(sym_shape_str_list), 1) - np.testing.assert_equal( - sym_shape_str_list[0].find(self.expected_sym_shape), - 0, - 'output shape is not expected!', - ) - out = net(self.x) - return out - - -class ArangeNet(paddle.nn.Layer): - def __init__(self): - super().__init__() - - def forward(self, in_0, in_1, in_2): - if in_1 is None: - end = in_0 - out = paddle.arange(end) - else: - start, end, step = in_0, in_1, in_2 - out = paddle.arange(start, end, step) - - return out - - -class TestArangeOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.start = paddle.full([1], 0) - self.end = paddle.full([1], 5) - self.step = paddle.full([1], 1) - - self.expected_sym_shape = ( - 'shape[Mul(Add(S1, -S0), 1 / (S2))], data[NULL]' - ) - - def test_eval_symbolic(self): - net = ArangeNet() - - input_spec = [ - InputSpec(shape=[None], dtype='float32'), - InputSpec(shape=[None], dtype='float32'), - InputSpec(shape=[None], dtype='float32'), - ] - net = apply_to_static(net, False, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op(net, input_spec) - np.testing.assert_equal(len(sym_shape_str_list), 1) - np.testing.assert_equal( - sym_shape_str_list[0].find(self.expected_sym_shape), - 0, - 'output shape is not expected!', - ) - out = net(self.start, self.end, self.step) - return out - - -class ExpandNet(paddle.nn.Layer): - def __init__(self): - super().__init__() - - def forward(self, x, y): - out = paddle.expand(x, [paddle.shape(y)[1], paddle.shape(y)[0]]) - out = paddle.expand(x, [7, 5, paddle.shape(y)[0]]) - out = paddle.expand(x, [7, -1, paddle.shape(y)[0]]) - out = paddle.expand(x, [7, paddle.shape(y)[1], -1]) - - return out - - -class TestExpandOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.x = paddle.rand([1, 3], 'float32') - self.y = paddle.rand([3, 2], 'float32') - - self.expected_sym_shapes = [ - 'shape[S3, S2], data[NULL]', - 'shape[7, 5, S2], data[NULL]', - 'shape[7, S0, S2], data[NULL]', - 'shape[7, S3, S1], data[NULL]', - ] - - def test_eval_symbolic(self): - net = ExpandNet() - - input_spec = [ - InputSpec(shape=[None, None], dtype='float32'), - InputSpec(shape=[None, None], dtype='float32'), - ] - net = apply_to_static(net, False, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'pd_op.expand' - ) - np.testing.assert_equal( - len(sym_shape_str_list), len(self.expected_sym_shapes) - ) - for i in range(len(self.expected_sym_shapes)): - np.testing.assert_equal( - sym_shape_str_list[i].find(self.expected_sym_shapes[i]), - 0, - 'output shape is not expected!', - ) - out = net(self.x, self.y) - return out - - -class MatmulNet(paddle.nn.Layer): - def __init__(self): - super().__init__() - - def forward(self, x, y, trans_x, trans_y): - out = paddle.matmul(x, y, trans_x, trans_y) - - return out - - -class TestMatmulOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.cases = [ - # [x, y, trans_x, trans_y] - [np.random.rand(1, 3), np.random.rand(3, 2), False, False], - # with broadcast - [np.random.rand(10), np.random.rand(10), False, False], # [] - [np.random.rand(10, 5), np.random.rand(5), False, False], # [10] - [ - np.random.rand(10, 5, 2), - np.random.rand(2), - False, - False, - ], # [10, 5] - [ - np.random.rand(10, 5, 2), - np.random.rand(10, 2, 5), - False, - False, - ], # [10, 5, 5] - [ - np.random.rand(10, 1, 5, 2), - np.random.rand(1, 3, 2, 5), - False, - False, - ], # [10, 3, 5, 5] - # with transpose - [np.random.rand(3, 5), np.random.rand(3, 2), True, False], # [5, 2] - [np.random.rand(3, 5), np.random.rand(4, 5), False, True], # [3, 4] - ] - - self.expected = [ - 'shape[S0, S3], data[NULL]', - # with broadcast - 'shape[], data[NULL]', - 'shape[S0], data[NULL]', - 'shape[S0, S1], data[NULL]', - 'shape[Broadcast(S0, S3), S1, S5], data[NULL]', - 'shape[Broadcast(S0, S4), Broadcast(S1, S5), S2, S7], data[NULL]', - # with transpose - 'shape[S1, S3], data[NULL]', - 'shape[S0, S2], data[NULL]', - ] - - def test_eval_symbolic(self): - net = MatmulNet() - - for i in range(len(self.cases)): - x, y, trans_x, trans_y = self.cases[i] - x_spec = InputSpec( - shape=[None for index in range(len(x.shape))], dtype='float32' - ) - y_spec = InputSpec( - shape=[None for index in range(len(y.shape))], dtype='float32' - ) - - input_spec = [x_spec, y_spec, trans_x, trans_y] - net = apply_to_static(net, False, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'pd_op.matmul' - ) - np.testing.assert_equal(len(sym_shape_str_list), 1) - np.testing.assert_equal( - sym_shape_str_list[0].find(self.expected[i]), - 0, - f'in case i = {i}: output shape ({sym_shape_str_list[0]}) is not expected {(self.expected[i])}', - ) - - return True - - -class MaxNet(paddle.nn.Layer): - def __init__(self): - super().__init__() - - def forward(self, x): - out = paddle.max(x) - out = paddle.max(x, 0) - out = paddle.max(x, 1) - out = paddle.max(x, -1) - out = paddle.max(x, -2) - - # keepdim=True - out = paddle.max(x, keepdim=True) - out = paddle.max(x, 0, keepdim=True) - out = paddle.max(x, 1, keepdim=True) - out = paddle.max(x, -1, keepdim=True) - out = paddle.max(x, -2, keepdim=True) - - return out - - -class TestMaxOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.cases = [np.random.rand(2, 4)] - - self.expected = [ - [ - 'shape[], data[NULL]', - 'shape[S1], data[NULL]', - 'shape[S0], data[NULL]', - 'shape[S0], data[NULL]', - 'shape[S1], data[NULL]', - # keepdim=True - 'shape[1, 1], data[NULL]', - 'shape[1, S1], data[NULL]', - 'shape[S0, 1], data[NULL]', - 'shape[S0, 1], data[NULL]', - 'shape[1, S1], data[NULL]', - ] - ] - - def test_eval_symbolic(self): - net = MaxNet() - - for i in range(len(self.cases)): - x = self.cases[i] - x_spec = InputSpec( - shape=[None for index in range(len(x.shape))], dtype='float32' - ) - - input_spec = [x_spec] - net = apply_to_static(net, False, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'pd_op.max' - ) - np.testing.assert_equal( - len(sym_shape_str_list), len(self.expected[i]) - ) - for j in range(len(sym_shape_str_list)): - np.testing.assert_equal( - sym_shape_str_list[j].find(self.expected[i][j]), - 0, - f'in case i,j = {i},{j}: output shape ({sym_shape_str_list[j]}) is not expected {(self.expected[i][j])}', - ) - - return True - - -class MeshgridNet(paddle.nn.Layer): - def __init__(self): - super().__init__() - - def forward(self, x, y): - out_x, out_y = paddle.meshgrid(x, y) - return out_x, out_y - - -class TestMeshgridOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.x_cases = [np.random.rand(1), np.random.rand(10), np.random.rand(100), np.random.rand(1000)] - self.y_cases = [np.random.rand(1), np.random.rand(10), np.random.rand(1000), np.random.rand(100)] - - self.expected = [ - [ - 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', - ], - [ - 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', - ], - [ - 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', - ], - [ - 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', - ], - ] - - def test_eval_symbolic(self): - net = MeshgridNet() - - for i in range(len(self.x_cases)): - x = self.x_cases[i] - y = self.y_cases[i] - x_spec = InputSpec( - shape=[None for index in range(len(x.shape))], dtype='float32' - ) - y_spec = InputSpec( - shape=[None for index in range(len(y.shape))], dtype='float32' - ) - - input_spec = [x_spec, y_spec] - net = apply_to_static(net, False, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'pd_op.meshgrid' - ) - np.testing.assert_equal( - len(sym_shape_str_list), len(self.expected[i]) - ) - for j in range(len(sym_shape_str_list)): - np.testing.assert_equal( - sym_shape_str_list[j].find(self.expected[i][j]), - 0, - f'in case i,j = {i},{j}: output shape ({sym_shape_str_list[j]}) is not expected {(self.expected[i][j])}', - ) - - # TODO(WintersMontagne10335): Add builtin.meshgrid op infer symbolic shape test - # Not added because attribute `sym_shape_str` does not support multi-output op now. - # See also: paddle/fluid/pir/transforms/shape_optimization_pass.cc:144. - - return True - - -class TakeAlongAxisNet(paddle.nn.Layer): - def __init__(self): - super().__init__() - - def forward(self, x, indices): - out = paddle.take_along_axis(x, indices, axis=0) - out = paddle.take_along_axis(x, indices, axis=1) - out = paddle.take_along_axis(x, indices, axis=-1) - out = paddle.take_along_axis(x, indices, axis=-2) - - return out - - -class TestTakeAlongAxisOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.cases = [ - [ - np.random.rand(2, 3, 4), - np.ones([6, 3, 4], dtype='int32'), - ], - ] - - self.expected = [ - [ - 'shape[S3, S1, S2], data[NULL]', - 'shape[S0, S4, S2], data[NULL]', - 'shape[S0, S1, S5], data[NULL]', - 'shape[S0, S4, S2], data[NULL]', - ], - ] - - def test_eval_symbolic(self): - net = TakeAlongAxisNet() - - for i in range(len(self.cases)): - x, indices = self.cases[i] - x_spec = InputSpec( - shape=[None for _ in range(len(x.shape))], dtype='float32' - ) - indices_spec = InputSpec( - shape=[None for _ in range(len(indices.shape))], dtype='int32' - ) - - input_spec = [x_spec, indices_spec] - net = apply_to_static(net, False, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'pd_op.take_along_axis' - ) - np.testing.assert_equal( - len(sym_shape_str_list), len(self.expected[i]) - ) - for j in range(len(sym_shape_str_list)): - np.testing.assert_equal( - sym_shape_str_list[j].find(self.expected[i][j]), - 0, - f'in case i,j = {i},{j}: output shape ({sym_shape_str_list[j]}) is not expected {(self.expected[i][j])}', - ) - - return True - - -class PutAlongAxisNet(paddle.nn.Layer): - def __init__(self): - super().__init__() - - def forward(self, x, indices, value): - out = paddle.put_along_axis(x, indices, value, axis=0) - out = paddle.put_along_axis(x, indices, value, axis=1) - out = paddle.put_along_axis(x, indices, value, axis=-1) - - return out - - -class TestPutAlongAxisOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.cases = [ - [ - np.random.rand(2, 3, 4), - np.ones([2, 3, 4], dtype='int32'), - np.ones([2, 3, 4], dtype='float32'), - ], - ] - - self.expected = [ - [ - 'shape[S0, S1, S2], data[NULL]', - 'shape[S0, S1, S2], data[NULL]', - 'shape[S0, S1, S2], data[NULL]', - ], - ] - - def test_eval_symbolic(self): - net = PutAlongAxisNet() - - for i in range(len(self.cases)): - x, indices, value = self.cases[i] - x_spec = InputSpec( - shape=[None for _ in range(len(x.shape))], dtype='float32' - ) - indices_spec = InputSpec( - shape=[None for _ in range(len(indices.shape))], dtype='int32' - ) - value_spec = InputSpec( - shape=[None for _ in range(len(value.shape))], dtype='float32' - ) - - input_spec = [x_spec, indices_spec, value_spec] - net = apply_to_static(net, False, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'pd_op.put_along_axis' - ) - np.testing.assert_equal( - len(sym_shape_str_list), len(self.expected[i]) - ) - for j in range(len(sym_shape_str_list)): - np.testing.assert_equal( - sym_shape_str_list[j].find(self.expected[i][j]), - 0, - f'in case i,j = {i},{j}: output shape ({sym_shape_str_list[j]}) is not expected {(self.expected[i][j])}', - ) - - return True - - -class TransposeNet(paddle.nn.Layer): - def __init__(self): - super().__init__() - - def forward(self, x): - out = paddle.transpose(x, perm=[1, 0, 2]) - - x = x.reshape([2, 3, 2, 2]) - shape = paddle.shape(x) - out = shape.transpose(perm=(0,)) - - return out - - -class TestTransposeOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.cases = [np.random.rand(2, 3, 4)] - - self.expected = [ - ['shape[S1, S0, S2], data[NULL]', 'shape[4], data[2, 3, 2, 2]'] - ] - - def test_eval_symbolic(self): - net = TransposeNet() - - for i in range(len(self.cases)): - x = self.cases[i] - x_spec = InputSpec( - shape=[None for index in range(len(x.shape))], dtype='float32' - ) - - input_spec = [x_spec] - net = apply_to_static(net, False, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'pd_op.transpose' - ) - np.testing.assert_equal( - len(sym_shape_str_list), len(self.expected[i]) - ) - for j in range(len(sym_shape_str_list)): - np.testing.assert_equal( - sym_shape_str_list[j].find(self.expected[i][j]), - 0, - f'in case i,j = {i},{j}: output shape ({sym_shape_str_list[j]}) is not expected {(self.expected[i][j])}', - ) - - return True - - -class TrilNet(paddle.nn.Layer): - def __init__(self): - super().__init__() - - def forward(self, x): - out = paddle.tril(x) - - return out - - -class TestTrilOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.cases = [np.random.rand(2, 3, 4)] - - self.expected = [ - [ - 'shape[S0, S1, S2], data[NULL]', - ] - ] - - def test_eval_symbolic(self): - net = TrilNet() - - for i in range(len(self.cases)): - x = self.cases[i] - x_spec = InputSpec( - shape=[None for index in range(len(x.shape))], dtype='float32' - ) - - input_spec = [x_spec] - net = apply_to_static(net, False, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'pd_op.tril' - ) - np.testing.assert_equal( - len(sym_shape_str_list), len(self.expected[i]) - ) - for j in range(len(sym_shape_str_list)): - np.testing.assert_equal( - sym_shape_str_list[j].find(self.expected[i][j]), - 0, - f'in case i,j = {i},{j}: output shape ({sym_shape_str_list[j]}) is not expected {(self.expected[i][j])}', - ) - - return True - - -class SliceNet(paddle.nn.Layer): - def __init__(self): - super().__init__() - - def forward(self, x): - out = x[:, -1, :] - # out = x[1:3, 0:2, 2:4] - - # axes = [0, 1, 2] - # starts = [-3, 0, 2] - # ends = [3, 2, 4] - # out = paddle.slice(x, axes=axes, starts=starts, ends=ends) - - return out - - -class TestSliceOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.cases = [np.random.rand(4, 5, 6)] - - self.expected = [ - [ - 'shape[S0, S2], data[NULL]', - # 'shape[2, 2, 2], data[NULL]', - # 'shape[Add(3, -Add(-3, S0)), 2, 2]', - ] - ] - - def test_eval_symbolic(self): - net = SliceNet() - - for i in range(len(self.cases)): - x = self.cases[i] - x_spec = InputSpec( - shape=[None for index in range(len(x.shape))], dtype='float32' - ) - - input_spec = [x_spec] - # net = apply_to_static(net, False, input_spec) - net = apply_to_static(net, True, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'pd_op.slice' - ) - np.testing.assert_equal( - len(sym_shape_str_list), len(self.expected[i]) - ) - for j in range(len(sym_shape_str_list)): - np.testing.assert_equal( - sym_shape_str_list[j].find(self.expected[i][j]), - 0, - f'in case i,j = {i},{j}: output shape ({sym_shape_str_list[j]}) is not expected {(self.expected[i][j])}', - ) - - return True - - -class SplitNet(paddle.nn.Layer): - def __init__(self): - super().__init__() - - def forward(self, x): - out = paddle.split(x, [-1], axis=1) - out = paddle.split(x, [1, 2, -1], axis=1) - out = paddle.split(x, [1, -1], axis=1) - out = paddle.split(x, [1, 2, 3], axis=1) - out = paddle.split(x, [1, 2, x.shape[1]], axis=1) - - out = x.split([-1], axis=1) - out = x.split([1, 2, -1], axis=1) - out = x.split([1, -1], axis=1) - out = x.split([1, 2, 3], axis=1) - out = x.split([1, 2, x.shape[1]], axis=1) - - return out - - -class TestSplitOpInferSymbolicShape(TestBase): - def prepare_data(self): - self.cases = [np.random.rand(4, 6, 5)] - - self.expected = [ - [ - 'shape[S0, S1, S2], data[NULL]', - 'shape[S0, 1, S2], data[NULL], shape[S0, 2, S2], data[NULL], shape[S0, Add(S1, -3), S2], data[NULL]', - 'shape[S0, 1, S2], data[NULL], shape[S0, Add(S1, -1), S2], data[NULL]', - 'shape[S0, 1, S2], data[NULL], shape[S0, 2, S2], data[NULL], shape[S0, 3, S2], data[NULL]', - 'shape[S0, 1, S2], data[NULL], shape[S0, 2, S2], data[NULL], shape[S0, S1, S2], data[NULL]', - 'shape[S0, S1, S2], data[NULL]', - 'shape[S0, 1, S2], data[NULL], shape[S0, 2, S2], data[NULL], shape[S0, Add(S1, -3), S2], data[NULL]', - 'shape[S0, 1, S2], data[NULL], shape[S0, Add(S1, -1), S2], data[NULL]', - 'shape[S0, 1, S2], data[NULL], shape[S0, 2, S2], data[NULL], shape[S0, 3, S2], data[NULL]', - 'shape[S0, 1, S2], data[NULL], shape[S0, 2, S2], data[NULL], shape[S0, S1, S2], data[NULL]', - ] - ] - - def test_eval_symbolic(self): - net = SplitNet() - - for i in range(len(self.cases)): - x = self.cases[i] - x_spec = InputSpec( - shape=[None for index in range(len(x.shape))], dtype='float32' - ) - - input_spec = [x_spec] - net = apply_to_static(net, False, input_spec) - net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'pd_op.split' - ) - np.testing.assert_equal( - len(sym_shape_str_list), len(self.expected[i]) - ) - for j in range(len(sym_shape_str_list)): - np.testing.assert_equal( - sym_shape_str_list[j].find(self.expected[i][j]), - 0, - f'in case i,j = {i},{j}: output shape ({sym_shape_str_list[j]}) is not expected {(self.expected[i][j])}', - ) - - # TODO(fty1777): Add builtin.split op infer symbolic shape test - # Not added because attribute `sym_shape_str` does not support multi-output op now. - # See also: paddle/fluid/pir/transforms/shape_optimization_pass.cc:144. - - return True - - -if __name__ == '__main__': - unittest.main() From 4bd1b2edde82544c7b6389a6da46536a775d1630 Mon Sep 17 00:00:00 2001 From: WintersMontagne10335 <22251099@zju.edu.cn> Date: Sat, 16 Mar 2024 06:08:43 +0000 Subject: [PATCH 4/8] fix bugs --- .../multiary_infer_sym.cc | 16 +++---- .../pir/cinn/sub_graphs/test_sub_graph_54.py | 2 +- .../test_infer_sym_shape_multinary_op.py | 46 +++++++------------ 3 files changed, 26 insertions(+), 38 deletions(-) diff --git a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc index b4d73cd6426bb9..728e53aec19752 100644 --- a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc +++ b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc @@ -121,8 +121,8 @@ bool LogspaceOpInferSymbolicShape( return true; } -bool MeshgridOpInferSymbolicShape(pir::Operation *op, - pir::ShapeConstraintIRAnalysis *shape_analysis) { +bool MeshgridOpInferSymbolicShape( + pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { const auto &attributes = op->attributes(); const symbol::TensorListShapeOrDataDimExprs &shape_data_list = shape_analysis->GetShapeOrDataForValue(op->operand_source(0)) @@ -131,18 +131,18 @@ bool MeshgridOpInferSymbolicShape(pir::Operation *op, const symbol::ShapeOrDataDimExprs sym_shape_dim_exprs = [&] { symbol::TensorListShapeOrDataDimExprs shape_dim_exprs_list; std::vector vec; - - for(auto& shape_data : shape_data_list){ - if(shape_data.shape().size()==0){ + + for (auto &shape_data : shape_data_list) { + if (shape_data.shape().size() == 0) { vec.emplace_back(1); - }else{ + } else { vec.emplace_back(shape_data.shape()[0]); } } - auto shape_dim_exprs=symbol::TensorShapeOrDataDimExprs(vec); + auto shape_dim_exprs = symbol::TensorShapeOrDataDimExprs(vec); - for(auto& shape_data : shape_data_list){ + for (auto &shape_data : shape_data_list) { shape_dim_exprs_list.emplace_back(shape_dim_exprs); } diff --git a/test/ir/pir/cinn/sub_graphs/test_sub_graph_54.py b/test/ir/pir/cinn/sub_graphs/test_sub_graph_54.py index d8ce779f195126..6120b43cf9bdf7 100644 --- a/test/ir/pir/cinn/sub_graphs/test_sub_graph_54.py +++ b/test/ir/pir/cinn/sub_graphs/test_sub_graph_54.py @@ -127,7 +127,7 @@ def train(self, net, to_static, with_prim=False, with_cinn=False): def test_ast_prim_cinn(self): st_out = self.train(self.net, to_static=True) cinn_out = self.train( - self.net, to_static=True, with_prim=False, with_cinn=False + self.net, to_static=True, with_prim=True, with_cinn=True ) for st, cinn in zip( paddle.utils.flatten(st_out), paddle.utils.flatten(cinn_out) diff --git a/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py b/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py index 9fca0f3a161372..264ef02659c54a 100644 --- a/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py +++ b/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py @@ -71,29 +71,28 @@ def forward(self, x, y): return out_x, out_y -class TestMeshgridOpInferSymbolicShape(TestBase): +class MeshgridOpInferSymbolicShapeTest(TestBase): def prepare_data(self): - self.x_cases = [np.random.rand(1), np.random.rand(10), np.random.rand(100), np.random.rand(1000)] - self.y_cases = [np.random.rand(1), np.random.rand(10), np.random.rand(1000), np.random.rand(100)] + self.x_cases = [ + np.random.rand(1), + np.random.rand(10), + np.random.rand(100), + np.random.rand(1000), + ] + self.y_cases = [ + np.random.rand(1), + np.random.rand(10), + np.random.rand(1000), + np.random.rand(100), + ] self.expected = [ - [ - 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', - ], - [ - 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', - ], - [ - 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', - ], - [ - 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', - ], + 'shape[S0, S1], data[NULL], shape[S0, S1], data[NULL]', ] def test_eval_symbolic(self): net = MeshgridNet() - + for i in range(len(self.x_cases)): x = self.x_cases[i] y = self.y_cases[i] @@ -107,20 +106,9 @@ def test_eval_symbolic(self): input_spec = [x_spec, y_spec] net = apply_to_static(net, False, input_spec) net.eval() - - # check the infer result - sym_shape_str_list = get_sym_shape_str_for_op( - net, input_spec, 'pd_op.meshgrid' - ) - np.testing.assert_equal( - len(sym_shape_str_list), len(self.expected[i]) + check_infer_results( + net, input_spec, 'pd_op.meshgrid', self.expected ) - for j in range(len(sym_shape_str_list)): - np.testing.assert_equal( - sym_shape_str_list[j].find(self.expected[i][j]), - 0, - f'in case i,j = {i},{j}: output shape ({sym_shape_str_list[j]}) is not expected {(self.expected[i][j])}', - ) # TODO(WintersMontagne10335): Add builtin.meshgrid op infer symbolic shape test # Not added because attribute `sym_shape_str` does not support multi-output op now. From 0fb504d9842dce6cdda1e0574760328b64b6382b Mon Sep 17 00:00:00 2001 From: WintersMontagne10335 <22251099@zju.edu.cn> Date: Sat, 16 Mar 2024 07:49:44 +0000 Subject: [PATCH 5/8] fix bugs --- .../interface/infer_symbolic_shape/multiary_infer_sym.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc index 728e53aec19752..84a5145d602cba 100644 --- a/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc +++ b/paddle/fluid/pir/dialect/operator/interface/infer_symbolic_shape/multiary_infer_sym.cc @@ -123,7 +123,6 @@ bool LogspaceOpInferSymbolicShape( bool MeshgridOpInferSymbolicShape( pir::Operation *op, pir::ShapeConstraintIRAnalysis *shape_analysis) { - const auto &attributes = op->attributes(); const symbol::TensorListShapeOrDataDimExprs &shape_data_list = shape_analysis->GetShapeOrDataForValue(op->operand_source(0)) .dyn_cast(); @@ -142,7 +141,7 @@ bool MeshgridOpInferSymbolicShape( auto shape_dim_exprs = symbol::TensorShapeOrDataDimExprs(vec); - for (auto &shape_data : shape_data_list) { + for (size_t i = 0; i < shape_data_list.size(); i++) { shape_dim_exprs_list.emplace_back(shape_dim_exprs); } From 3746197563debe5855d0e3859fc0cd63cf44bb7f Mon Sep 17 00:00:00 2001 From: WintersMontagne10335 <22251099@zju.edu.cn> Date: Sat, 16 Mar 2024 09:12:39 +0000 Subject: [PATCH 6/8] fix bugs --- test/ir/pir/cinn/sub_graphs/test_sub_graph_54.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ir/pir/cinn/sub_graphs/test_sub_graph_54.py b/test/ir/pir/cinn/sub_graphs/test_sub_graph_54.py index 6120b43cf9bdf7..d8ce779f195126 100644 --- a/test/ir/pir/cinn/sub_graphs/test_sub_graph_54.py +++ b/test/ir/pir/cinn/sub_graphs/test_sub_graph_54.py @@ -127,7 +127,7 @@ def train(self, net, to_static, with_prim=False, with_cinn=False): def test_ast_prim_cinn(self): st_out = self.train(self.net, to_static=True) cinn_out = self.train( - self.net, to_static=True, with_prim=True, with_cinn=True + self.net, to_static=True, with_prim=False, with_cinn=False ) for st, cinn in zip( paddle.utils.flatten(st_out), paddle.utils.flatten(cinn_out) From 61ecaa3a3888a80737be4df4edc3d743eb7a937d Mon Sep 17 00:00:00 2001 From: Winters Montagne <118546135+WintersMontagne10335@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:15:59 +0800 Subject: [PATCH 7/8] Update test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py Co-authored-by: Bo Zhang <105368690+zhangbopd@users.noreply.github.com> --- test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py b/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py index 264ef02659c54a..1ed3b2a52d8dd0 100644 --- a/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py +++ b/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py @@ -97,7 +97,7 @@ def test_eval_symbolic(self): x = self.x_cases[i] y = self.y_cases[i] x_spec = InputSpec( - shape=[None for index in range(len(x.shape))], dtype='float32' + shape=[None for _ in range(len(x.shape))], dtype='float32' ) y_spec = InputSpec( shape=[None for index in range(len(y.shape))], dtype='float32' From 4d0374dbfc6323cc1c63780bfd09c3aaef427741 Mon Sep 17 00:00:00 2001 From: Winters Montagne <118546135+WintersMontagne10335@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:16:05 +0800 Subject: [PATCH 8/8] Update test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py Co-authored-by: Bo Zhang <105368690+zhangbopd@users.noreply.github.com> --- test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py b/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py index 1ed3b2a52d8dd0..aab4326d7dd50a 100644 --- a/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py +++ b/test/ir/pir/cinn/symbolic/test_infer_sym_shape_multinary_op.py @@ -100,7 +100,7 @@ def test_eval_symbolic(self): shape=[None for _ in range(len(x.shape))], dtype='float32' ) y_spec = InputSpec( - shape=[None for index in range(len(y.shape))], dtype='float32' + shape=[None for _ in range(len(y.shape))], dtype='float32' ) input_spec = [x_spec, y_spec]