Files
paddlepaddle--paddle/paddle/cinn/operator_fusion/fusion_tracker/tracker.h
T
2026-07-13 12:40:42 +08:00

261 lines
8.3 KiB
C++

// 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 "paddle/cinn/operator_fusion/pir_graph_analyzing/loop_axis_mapping.h"
#include "paddle/cinn/operator_fusion/utils.h"
namespace cinn::fusion {
enum InstructionType {
T_Base,
T_Copy,
T_Combine,
T_Return,
T_InitPattern,
T_TrivialInline,
T_TmpTransform,
T_TrivialLoopAlign,
T_AxisTransform,
};
struct FusionInstruction {
using FusionInstrPtr = std::shared_ptr<FusionInstruction>;
virtual InstructionType type() const { return T_Base; }
virtual std::string DebugStr() const { return "BaseInstr"; }
virtual FusionInstrPtr Clone() {
return std::make_shared<FusionInstruction>(*this);
}
};
using FusionInstrPtr = std::shared_ptr<FusionInstruction>;
struct CopyInstr : public FusionInstruction {
CopyInstr(const std::string& origin_name, const std::string& new_name)
: origin_name_(origin_name), new_name_(new_name) {}
virtual InstructionType type() const { return T_Copy; }
virtual FusionInstrPtr Clone() { return std::make_shared<CopyInstr>(*this); }
std::string origin_name_;
std::string new_name_;
virtual std::string DebugStr() const {
return "CopyInstr || " + origin_name_ + " => " + new_name_;
}
};
struct CombineInstr : public FusionInstruction {
CombineInstr(const std::vector<std::string>& names, const std::string& result)
: names_(names), result_(result) {}
virtual InstructionType type() const { return T_Combine; }
virtual FusionInstrPtr Clone() {
return std::make_shared<CombineInstr>(*this);
}
std::vector<std::string> names_;
std::string result_;
virtual std::string DebugStr() const {
std::stringstream ss;
ss << "CombineInstr || ";
for (auto name : names_) {
ss << name << ", ";
}
ss << "=> " << result_;
return ss.str();
}
};
struct ReturnInstr : public FusionInstruction {
explicit ReturnInstr(const std::string& target) : target_(target) {}
virtual InstructionType type() const { return T_Return; }
virtual FusionInstrPtr Clone() {
return std::make_shared<ReturnInstr>(*this);
}
std::string target_;
virtual std::string DebugStr() const { return "ReturnInstr || " + target_; }
};
// struct RemovePatternInstr : public FusionInstruction {};
struct InitPatternInstr : public FusionInstruction {
private:
// we can't just use operation* to identify a unique op because pass change
// the program.
int idx_in_fusion_op = -1;
std::string op_name;
public:
InitPatternInstr(pir::Operation* op, const std::string& result)
: op_(op), result_(result) {
op_name = op->name();
}
void set_idx(int idx) { idx_in_fusion_op = idx; }
int get_idx() const {
PADDLE_ENFORCE_NE(
idx_in_fusion_op,
-1,
::common::errors::InvalidArgument("FusionPattern is not initialized."));
return idx_in_fusion_op;
}
virtual InstructionType type() const { return T_InitPattern; }
virtual FusionInstrPtr Clone() {
return std::make_shared<InitPatternInstr>(*this);
}
pir::Operation* op_;
std::string result_;
virtual std::string DebugStr() const {
std::ostringstream ss;
ss << "InitPatternInstr || " + op_name + " => " + result_ + " index = ("
<< idx_in_fusion_op << ")";
return ss.str();
}
};
struct TrivialInlineInstr : public FusionInstruction {
TrivialInlineInstr(const std::string& upstream,
const std::string& downstream,
const std::string& result)
: upstream_(upstream), downstream_(downstream), result_(result) {}
virtual InstructionType type() const { return T_TrivialInline; }
virtual FusionInstrPtr Clone() {
return std::make_shared<TrivialInlineInstr>(*this);
}
std::string upstream_;
std::string downstream_;
std::string result_;
virtual std::string DebugStr() const {
return "TrivialInlineInstr || " + upstream_ + ", " + downstream_ + " => " +
result_;
}
};
struct TmpTransformInstr : public FusionInstruction {
TmpTransformInstr(const std::string& upstream,
const std::string& downstream,
const std::string& out_upstream,
const std::string& out_downstream,
const std::vector<size_t>& fake_reduce_iter_idx = {})
: upstream_(upstream),
downstream_(downstream),
out_downstream_(out_downstream),
out_upstream_(out_upstream),
fake_reduce_iter_idx_(fake_reduce_iter_idx) {}
InstructionType type() const override { return T_TmpTransform; }
virtual FusionInstrPtr Clone() {
return std::make_shared<TmpTransformInstr>(*this);
}
std::string upstream_;
std::string downstream_;
std::string out_upstream_;
std::string out_downstream_;
std::vector<size_t> fake_reduce_iter_idx_;
std::string DebugStr() const override {
return "TmpTransformInstr || " + upstream_ + ", " + downstream_ + " => " +
out_upstream_ + ", " + out_downstream_;
}
};
struct TrivialLoopAlignInstr : public FusionInstruction {
TrivialLoopAlignInstr(const std::string& upstream,
const std::string& downstream,
const std::string& result,
const std::vector<size_t>& fake_reduce_iter_idx)
: upstream_(upstream),
downstream_(downstream),
result_(result),
fake_reduce_iter_idx_(fake_reduce_iter_idx) {}
virtual InstructionType type() const { return T_TrivialLoopAlign; }
virtual FusionInstrPtr Clone() {
return std::make_shared<TrivialLoopAlignInstr>(*this);
}
std::string upstream_;
std::string downstream_;
std::string result_;
std::vector<size_t> fake_reduce_iter_idx_;
virtual std::string DebugStr() const {
return "TrivialLoopAlignInstr || " + upstream_ + ", " + downstream_ +
" => " + result_;
}
};
struct AxisTransformInstr : public FusionInstruction {
AxisTransformInstr(const std::string& source,
const std::string& target,
const AxisTransformRoute& axis_transform_route)
: source_(source),
target_(target),
axis_transform_route_(axis_transform_route) {}
virtual InstructionType type() const { return T_AxisTransform; }
virtual FusionInstrPtr Clone() {
return std::make_shared<AxisTransformInstr>(*this);
}
std::string source_;
std::string target_;
AxisTransformRoute axis_transform_route_;
virtual std::string DebugStr() const {
return "AxisTransformInstr || " + source_ + " => " + target_;
}
};
template <typename T>
std::shared_ptr<T> dynamic_cast_instr_with_err(FusionInstrPtr instr) {
auto chile_instr = std::dynamic_pointer_cast<T>(instr);
PADDLE_ENFORCE_NOT_NULL(
chile_instr,
::common::errors::InvalidArgument("Cast Fusion Instr Failed."));
return chile_instr;
}
struct FusionTracker {
using FusionTrackerPtr = std::shared_ptr<FusionTracker>;
FusionTracker() = default;
explicit FusionTracker(const FusionTrackerPtr& other) {
ExtendVector(&instructions_, other->instructions_);
}
FusionTracker(const FusionTrackerPtr& up, const FusionTrackerPtr& down) {
ExtendVector(&instructions_, up->instructions_);
ExtendVector(&instructions_, down->instructions_);
}
void append(FusionInstrPtr instr) { instructions_.emplace_back(instr); }
FusionTrackerPtr Clone() {
auto new_tracker = std::make_shared<FusionTracker>();
std::vector<FusionInstrPtr> new_instructions;
for (auto instr : instructions_) {
new_tracker->append(instr->Clone());
}
return new_tracker;
}
std::string DebugStr() const {
std::stringstream ss;
ss << "FusionTracker: \n";
for (auto instr : instructions_) {
ss << " " << instr->DebugStr() << "\n";
}
return ss.str();
}
std::vector<FusionInstrPtr> instructions_;
};
using FusionTrackerPtr = std::shared_ptr<FusionTracker>;
} // namespace cinn::fusion