From 6e3d41662404ea1125051ac03616ddb44996b4ae Mon Sep 17 00:00:00 2001 From: Aurelius84 Date: Wed, 3 Jan 2024 09:01:39 +0000 Subject: [PATCH 1/6] [PIR] Support Operation::Clone Interface --- paddle/pir/core/ir_mapping.h | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 paddle/pir/core/ir_mapping.h diff --git a/paddle/pir/core/ir_mapping.h b/paddle/pir/core/ir_mapping.h new file mode 100644 index 0000000000000..d8528e60a980b --- /dev/null +++ b/paddle/pir/core/ir_mapping.h @@ -0,0 +1,37 @@ +// 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. +#pragma once +#include +#include "paddle/common/enforce.h" +#include "paddle/pir/core/block.h" + +namespace pir { + +class IRMapping { + public: + void map(Value from, Value to) { value_map_[from] = to; } + + Value lookup(Value from) const { + IR_ENFORCE(value_map_.count(from) > 0, "Not Found Value in IRMapping."); + return value_map_.at(from); + } + void earse(Value from) { value_map_.erase(from); } + + void clear() { value_map_.clear(); } + + private: + std::unordered_map value_map_; +}; + +} // namespace pir From 56f5ffa6b61f98c30f19319ca24ac84d53a3e026 Mon Sep 17 00:00:00 2001 From: Aurelius84 Date: Wed, 3 Jan 2024 09:04:05 +0000 Subject: [PATCH 2/6] [PIR] Support Operation::Clone Interface --- paddle/cinn/hlir/framework/pir/group.h | 40 +++++++++++++++++++++++++- paddle/pir/core/operation.cc | 30 +++++++++++++++++++ paddle/pir/core/operation.h | 24 +++++++++++++++- 3 files changed, 92 insertions(+), 2 deletions(-) diff --git a/paddle/cinn/hlir/framework/pir/group.h b/paddle/cinn/hlir/framework/pir/group.h index 870a159d49c92..dbdc3009929ad 100644 --- a/paddle/cinn/hlir/framework/pir/group.h +++ b/paddle/cinn/hlir/framework/pir/group.h @@ -14,7 +14,9 @@ #pragma once #include +#include #include +#include "glog/logging.h" #include "paddle/cinn/adt/graph_symbolic_dim_infer_ctx.h" #include "paddle/cinn/hlir/framework/op.h" @@ -34,8 +36,17 @@ namespace framework { namespace pir { using framework::OpPatternKind; -// TODO(Aurelius84): Need to be replaced with CinnGroupOp struct Group { + // Control the clone strategy for Group. + class Options { + public: + Options() : only_clone_ops(true) {} + bool OnlyCloneOps() const { return only_clone_ops; } + + private: + bool only_clone_ops = false; + }; + public: Group() = default; Group(const Group&) = delete; @@ -47,6 +58,33 @@ struct Group { explicit Group(std::initializer_list<::pir::Operation*> group_ops) : ops(group_ops) {} + Group& Clone(::pir::Block* target_block, + ::pir::IRMapping& ir_mapping, + const Options& option = Options()) const { + CHECK_EQ(option.OnlyCloneOps(), true) + << "Only Support Clone Group ops information."; + std::vector<::pir::Operation*> new_ops; + // Mapper from original to new ops. + std::unordered_map<::pir::Operation*, ::pir::Operation*> ops_mapper; + ::pir::CloneOptions clone_options(false, true); + for (auto* op : this->ops_set) { + auto* new_op = op->Clone(target_block, ir_mapping, clone_options); + new_ops.push_back(new_op); + ops_mapper[op] = new_op; + } + // Construct Base information for new Group + Group new_group(new_ops); + this->CollectOps(); + for (auto& iter : this->input_ops) { + new_group.input_ops[ops_mapper[iter.first]] = iter.second; + } + for (auto* op : this->output_ops) { + new_group.output_ops.insert(ops_mapper[op]); + } + + return new_group; + } + // distance to last group. int depth{0}; int max_depth{0}; diff --git a/paddle/pir/core/operation.cc b/paddle/pir/core/operation.cc index c0ce8842155ab..fd0e41f024b11 100644 --- a/paddle/pir/core/operation.cc +++ b/paddle/pir/core/operation.cc @@ -137,6 +137,36 @@ Operation *Operation::Create(const std::vector &inputs, return op; } +Operation *Operation::Clone(Block *target_block, + IRMapping &ir_mapping, + CloneOptions options) { + IR_ENFORCE(options.IsCloneRegions() || num_regions_ > 0, + "Operation CloneOperands is unimplemented currently."); + IR_ENFORCE(num_successors_ == 0, + "Operation::Clone is not unimplemented for multiple successors."); + + auto inputs = operands_source(); + if (options.IsCloneOperands()) { + // replace value by IRMapping inplacely. + for (auto &value : inputs) { + value = ir_mapping.lookup(value); + } + } + + std::vector output_types; + for (auto &result : results()) { + output_types.push_back(result.type()); + } + auto *new_op = Create(inputs, attributes_, output_types, info_, num_regions_); + // record outputs mapping info + for (int i = 0; i < num_results_; ++i) { + ir_mapping.map(result(i), new_op->result(i)); + } + // transfer ownership into target block + new_op->MoveTo(target_block, target_block->end()); + return new_op; +} + // Call destructors for Region , OpResults, Operation, and OpOperands in // sequence, and finally free memory. void Operation::Destroy() { diff --git a/paddle/pir/core/operation.h b/paddle/pir/core/operation.h index ea31c85ca7c26..5fcf3d936db78 100644 --- a/paddle/pir/core/operation.h +++ b/paddle/pir/core/operation.h @@ -20,12 +20,12 @@ #include "paddle/common/enforce.h" #include "paddle/common/macros.h" #include "paddle/pir/core/block.h" +#include "paddle/pir/core/ir_mapping.h" #include "paddle/pir/core/iterator.h" #include "paddle/pir/core/op_info.h" #include "paddle/pir/core/operation_utils.h" #include "paddle/pir/core/type.h" #include "paddle/pir/core/visitors.h" - namespace pir { class OpBase; class Program; @@ -37,6 +37,20 @@ class OpResultImpl; class OpOperendImpl; } // namespace detail +class CloneOptions { + public: + CloneOptions() : clone_regions_{false}, clone_operands_{false} {} + CloneOptions(bool clone_regions, bool clone_operands) + : clone_regions_(clone_regions), clone_operands_(clone_operands) {} + + bool IsCloneRegions() const { return clone_regions_; } + bool IsCloneOperands() const { return clone_operands_; } + + private: + bool clone_regions_{true}; + bool clone_operands_{true}; +}; + class IR_API alignas(8) Operation final : public DoubleLevelContainer { public: @@ -53,6 +67,14 @@ class IR_API alignas(8) Operation final size_t num_regions = 0, const std::vector &successors = {}); static Operation *Create(OperationArgument &&op_argument); + + /// + /// \brief Deep copy all information and create a new operation. + /// TODO(dev): Need hidden target_block argument in the future. + /// + Operation *Clone(Block *target_block, + IRMapping &ir_mapping, + CloneOptions options = CloneOptions()); /// /// \brief Destroy the operation objects and free memory by create(). /// From e4d447a32a6ba05ac35f2e4b6c10ea5cd50b5512 Mon Sep 17 00:00:00 2001 From: Aurelius84 Date: Wed, 3 Jan 2024 09:53:41 +0000 Subject: [PATCH 3/6] fix comment --- paddle/cinn/hlir/framework/pir/group.h | 7 +++++-- paddle/pir/core/ir_mapping.h | 10 +++++----- paddle/pir/core/operation.cc | 6 +----- paddle/pir/core/operation.h | 4 +--- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/paddle/cinn/hlir/framework/pir/group.h b/paddle/cinn/hlir/framework/pir/group.h index dbdc3009929ad..51c387d7f5f68 100644 --- a/paddle/cinn/hlir/framework/pir/group.h +++ b/paddle/cinn/hlir/framework/pir/group.h @@ -59,7 +59,7 @@ struct Group { : ops(group_ops) {} Group& Clone(::pir::Block* target_block, - ::pir::IRMapping& ir_mapping, + ::pir::IrMapping& ir_mapping, const Options& option = Options()) const { CHECK_EQ(option.OnlyCloneOps(), true) << "Only Support Clone Group ops information."; @@ -68,7 +68,10 @@ struct Group { std::unordered_map<::pir::Operation*, ::pir::Operation*> ops_mapper; ::pir::CloneOptions clone_options(false, true); for (auto* op : this->ops_set) { - auto* new_op = op->Clone(target_block, ir_mapping, clone_options); + auto* new_op = op->Clone(ir_mapping, clone_options); + // NOTE(dev): Must call MoveTo to deal with ownership, otherwise it + // will lead memory-leak. + new_op->MoveTo(target_block); new_ops.push_back(new_op); ops_mapper[op] = new_op; } diff --git a/paddle/pir/core/ir_mapping.h b/paddle/pir/core/ir_mapping.h index d8528e60a980b..607c8cc0704f5 100644 --- a/paddle/pir/core/ir_mapping.h +++ b/paddle/pir/core/ir_mapping.h @@ -18,17 +18,17 @@ namespace pir { -class IRMapping { +class IrMapping { public: - void map(Value from, Value to) { value_map_[from] = to; } + void Add(Value from, Value to) { value_map_[from] = to; } - Value lookup(Value from) const { + Value Lookup(Value from) const { IR_ENFORCE(value_map_.count(from) > 0, "Not Found Value in IRMapping."); return value_map_.at(from); } - void earse(Value from) { value_map_.erase(from); } + void Earse(Value from) { value_map_.erase(from); } - void clear() { value_map_.clear(); } + void Clear() { value_map_.clear(); } private: std::unordered_map value_map_; diff --git a/paddle/pir/core/operation.cc b/paddle/pir/core/operation.cc index fd0e41f024b11..6cae0ebd717b4 100644 --- a/paddle/pir/core/operation.cc +++ b/paddle/pir/core/operation.cc @@ -137,9 +137,7 @@ Operation *Operation::Create(const std::vector &inputs, return op; } -Operation *Operation::Clone(Block *target_block, - IRMapping &ir_mapping, - CloneOptions options) { +Operation *Operation::Clone(IrMapping &ir_mapping, CloneOptions options) { IR_ENFORCE(options.IsCloneRegions() || num_regions_ > 0, "Operation CloneOperands is unimplemented currently."); IR_ENFORCE(num_successors_ == 0, @@ -162,8 +160,6 @@ Operation *Operation::Clone(Block *target_block, for (int i = 0; i < num_results_; ++i) { ir_mapping.map(result(i), new_op->result(i)); } - // transfer ownership into target block - new_op->MoveTo(target_block, target_block->end()); return new_op; } diff --git a/paddle/pir/core/operation.h b/paddle/pir/core/operation.h index 5fcf3d936db78..0dafcdd7a5b2b 100644 --- a/paddle/pir/core/operation.h +++ b/paddle/pir/core/operation.h @@ -70,10 +70,8 @@ class IR_API alignas(8) Operation final /// /// \brief Deep copy all information and create a new operation. - /// TODO(dev): Need hidden target_block argument in the future. /// - Operation *Clone(Block *target_block, - IRMapping &ir_mapping, + Operation *Clone(IrMapping &ir_mapping, CloneOptions options = CloneOptions()); /// /// \brief Destroy the operation objects and free memory by create(). From b5a9531bfddae319914d0a0dab9425a661edc93c Mon Sep 17 00:00:00 2001 From: Aurelius84 Date: Wed, 3 Jan 2024 11:09:48 +0000 Subject: [PATCH 4/6] fix typo --- paddle/cinn/hlir/framework/pir/group.h | 2 +- paddle/pir/core/operation.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/paddle/cinn/hlir/framework/pir/group.h b/paddle/cinn/hlir/framework/pir/group.h index 51c387d7f5f68..6928d4a0eafa1 100644 --- a/paddle/cinn/hlir/framework/pir/group.h +++ b/paddle/cinn/hlir/framework/pir/group.h @@ -71,7 +71,7 @@ struct Group { auto* new_op = op->Clone(ir_mapping, clone_options); // NOTE(dev): Must call MoveTo to deal with ownership, otherwise it // will lead memory-leak. - new_op->MoveTo(target_block); + new_op->MoveTo(target_block, target_block->end()); new_ops.push_back(new_op); ops_mapper[op] = new_op; } diff --git a/paddle/pir/core/operation.cc b/paddle/pir/core/operation.cc index 6cae0ebd717b4..600838069df5b 100644 --- a/paddle/pir/core/operation.cc +++ b/paddle/pir/core/operation.cc @@ -147,7 +147,7 @@ Operation *Operation::Clone(IrMapping &ir_mapping, CloneOptions options) { if (options.IsCloneOperands()) { // replace value by IRMapping inplacely. for (auto &value : inputs) { - value = ir_mapping.lookup(value); + value = ir_mapping.Lookup(value); } } @@ -158,7 +158,7 @@ Operation *Operation::Clone(IrMapping &ir_mapping, CloneOptions options) { auto *new_op = Create(inputs, attributes_, output_types, info_, num_regions_); // record outputs mapping info for (int i = 0; i < num_results_; ++i) { - ir_mapping.map(result(i), new_op->result(i)); + ir_mapping.Add(result(i), new_op->result(i)); } return new_op; } From fc43816cf5656e12fb9e53a124703fc9ab881e06 Mon Sep 17 00:00:00 2001 From: Aurelius84 Date: Wed, 3 Jan 2024 11:58:49 +0000 Subject: [PATCH 5/6] fix int --- paddle/pir/core/operation.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paddle/pir/core/operation.cc b/paddle/pir/core/operation.cc index 600838069df5b..0a8e26d788ca1 100644 --- a/paddle/pir/core/operation.cc +++ b/paddle/pir/core/operation.cc @@ -157,7 +157,7 @@ Operation *Operation::Clone(IrMapping &ir_mapping, CloneOptions options) { } auto *new_op = Create(inputs, attributes_, output_types, info_, num_regions_); // record outputs mapping info - for (int i = 0; i < num_results_; ++i) { + for (uint32_t i = 0; i < num_results_; ++i) { ir_mapping.Add(result(i), new_op->result(i)); } return new_op; From c5b861a44bca30c3b66a6f8356f9dfb67d643f1c Mon Sep 17 00:00:00 2001 From: Aurelius84 Date: Wed, 3 Jan 2024 12:06:54 +0000 Subject: [PATCH 6/6] modify into shared_ptr --- paddle/cinn/hlir/framework/pir/group.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/paddle/cinn/hlir/framework/pir/group.h b/paddle/cinn/hlir/framework/pir/group.h index 6928d4a0eafa1..2cd3b9b9dedda 100644 --- a/paddle/cinn/hlir/framework/pir/group.h +++ b/paddle/cinn/hlir/framework/pir/group.h @@ -13,6 +13,7 @@ // limitations under the License. #pragma once +#include #include #include #include @@ -58,9 +59,9 @@ struct Group { explicit Group(std::initializer_list<::pir::Operation*> group_ops) : ops(group_ops) {} - Group& Clone(::pir::Block* target_block, - ::pir::IrMapping& ir_mapping, - const Options& option = Options()) const { + std::shared_ptr Clone(::pir::Block* target_block, + ::pir::IrMapping& ir_mapping, + const Options& option = Options()) const { CHECK_EQ(option.OnlyCloneOps(), true) << "Only Support Clone Group ops information."; std::vector<::pir::Operation*> new_ops; @@ -76,13 +77,13 @@ struct Group { ops_mapper[op] = new_op; } // Construct Base information for new Group - Group new_group(new_ops); + auto new_group = std::make_shared(new_ops); this->CollectOps(); for (auto& iter : this->input_ops) { - new_group.input_ops[ops_mapper[iter.first]] = iter.second; + new_group->input_ops[ops_mapper[iter.first]] = iter.second; } for (auto* op : this->output_ops) { - new_group.output_ops.insert(ops_mapper[op]); + new_group->output_ops.insert(ops_mapper[op]); } return new_group;