205 lines
6.2 KiB
C++
205 lines
6.2 KiB
C++
// Copyright (c) 2021 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/fluid/framework/ir/pass.h"
|
|
#include "paddle/phi/core/framework/pass_desc.pb.h"
|
|
|
|
namespace paddle {
|
|
namespace framework {
|
|
namespace ir {
|
|
|
|
// Generate a substitute pass from protobuf.
|
|
class PADDLE_API GeneratePass : public Pass {
|
|
public:
|
|
// from binary_str
|
|
explicit GeneratePass(const std::string& binary_str,
|
|
const std::string& pass_type = "");
|
|
// from PassDesc/MultiPassDesc
|
|
explicit GeneratePass(const proto::MultiPassDesc& multi_pass_desc,
|
|
const std::string& pass_type = "");
|
|
|
|
protected:
|
|
void ApplyImpl(Graph* graph) const override;
|
|
|
|
private:
|
|
GeneratePass() = delete;
|
|
DISABLE_COPY_AND_ASSIGN(GeneratePass);
|
|
// Verify desc
|
|
void VerifyDesc() const;
|
|
// Verify graph
|
|
static bool VerifyGraph(const Graph& graph);
|
|
|
|
proto::MultiPassDesc multi_pass_desc_;
|
|
};
|
|
|
|
namespace generate_pass {
|
|
|
|
class VarHelper;
|
|
class OpHelper;
|
|
class SubgraphHelper;
|
|
|
|
// VarHelper is used to represent a variable node.
|
|
class PADDLE_API VarHelper {
|
|
public:
|
|
enum class Type { kInput, kOutput };
|
|
|
|
explicit VarHelper(const char* name);
|
|
VarHelper(const std::string& name, Type type);
|
|
|
|
std::string name_;
|
|
Type type_;
|
|
};
|
|
|
|
// OpHelper is used to represent a operator node.
|
|
class OpHelper {
|
|
public:
|
|
// Convert multiple inputs.
|
|
struct Arguments {
|
|
PADDLE_API Arguments(const char* parameter, const VarHelper& var_helper);
|
|
PADDLE_API Arguments(const char* parameter,
|
|
std::initializer_list<VarHelper> var_helpers);
|
|
|
|
std::string parameter_;
|
|
std::vector<VarHelper> var_helpers_;
|
|
};
|
|
|
|
PADDLE_API OpHelper(const char* type, SubgraphHelper* subgraph_helper);
|
|
|
|
PADDLE_API OpHelper& operator()(const Arguments& input);
|
|
PADDLE_API OpHelper& operator()(std::initializer_list<Arguments> inputs);
|
|
|
|
PADDLE_API VarHelper Out(const char* name);
|
|
|
|
private:
|
|
OpHelper() = delete;
|
|
DISABLE_COPY_AND_ASSIGN(OpHelper);
|
|
|
|
const char* type_;
|
|
proto::OpDesc* op_desc_;
|
|
SubgraphHelper* subgraph_helper_;
|
|
};
|
|
|
|
/*
|
|
* SubgraphHelper is used to define pattern/replace subgraphs.
|
|
*
|
|
* Use lambda expression to define subgraph like Python. SubgraphHelper
|
|
* converts lambda expression to ProgramDesc.
|
|
*
|
|
* In order to define a subgraph, user need to use VarHelper and OpHelper.
|
|
* Use the macros instead of class names, so user can develop better and
|
|
* don't need to know too much about underlying implementation.
|
|
*
|
|
* An example of defining a subgraph as follows:
|
|
*
|
|
* SUBGRAPH_(subgraph)([subgraph=&subgraph](VAR_(x), VAR_(y), VAR_(z)) {
|
|
* auto ewadd1 = OP_(elementwise_add)({{"X", x}, {"Y", y}}).Out("Out");
|
|
* auto ewadd2 = OP_(elementwise_add)({{"X", ewadd1}, {"Y", z}}).Out("Out");
|
|
* return ewadd2;
|
|
* });
|
|
*
|
|
*/
|
|
class SubgraphHelper {
|
|
public:
|
|
SubgraphHelper() = default;
|
|
// The lambda expression is a prvalue expression.
|
|
template <typename T>
|
|
SubgraphHelper& operator=(const T&& f) {
|
|
proto::BlockDesc* block = program_desc_.add_blocks();
|
|
block->set_idx(0);
|
|
block->set_parent_idx(0);
|
|
AddOutputVars(f());
|
|
return *this;
|
|
}
|
|
|
|
proto::ProgramDesc* ProgramDesc();
|
|
const proto::ProgramDesc& ProgramDesc() const;
|
|
const std::vector<std::string>& InputVars() const;
|
|
const std::vector<std::string>& OutputVars() const;
|
|
|
|
PADDLE_API void AddInputVar(const std::string& name);
|
|
|
|
PADDLE_API void AddOutputVars(const VarHelper& var_helper);
|
|
|
|
template <size_t i,
|
|
typename... Ts,
|
|
std::enable_if_t<i + 1 < sizeof...(Ts)>* = nullptr>
|
|
void AddOutputVars(const std::tuple<Ts...>& outputs) {
|
|
AddOutputVars(std::get<i>(outputs));
|
|
AddOutputVars<i + 1>(outputs);
|
|
}
|
|
|
|
template <size_t i,
|
|
typename... Ts,
|
|
std::enable_if_t<i + 1 == sizeof...(Ts)>* = nullptr>
|
|
void AddOutputVars(const std::tuple<Ts...>& outputs) {
|
|
AddOutputVars(std::get<i>(outputs));
|
|
}
|
|
|
|
template <typename... Ts>
|
|
void AddOutputVars(const std::tuple<Ts...>& outputs) {
|
|
AddOutputVars<0>(outputs);
|
|
}
|
|
|
|
private:
|
|
DISABLE_COPY_AND_ASSIGN(SubgraphHelper);
|
|
std::vector<std::string> input_vars_;
|
|
std::vector<std::string> output_vars_;
|
|
proto::ProgramDesc program_desc_;
|
|
};
|
|
|
|
} // namespace generate_pass
|
|
|
|
class PADDLE_API PassPairs {
|
|
public:
|
|
using SubgraphType = generate_pass::SubgraphHelper;
|
|
|
|
PassPairs() = default;
|
|
PassPairs(const SubgraphType& pattern, const SubgraphType& replace);
|
|
|
|
void AddPassDesc(const SubgraphType& pattern, const SubgraphType& replace);
|
|
|
|
const proto::MultiPassDesc& MultiPassDesc() const;
|
|
|
|
private:
|
|
proto::MultiPassDesc multi_pass_desc_;
|
|
};
|
|
|
|
// Use function to register in CC.
|
|
template <PassPairs (*Functor)(void)>
|
|
class MacroPassHelper : public GeneratePass {
|
|
public:
|
|
MacroPassHelper() : GeneratePass(Functor().MultiPassDesc()) {}
|
|
};
|
|
|
|
#define VAR_(name) \
|
|
::paddle::framework::ir::generate_pass::VarHelper name = \
|
|
::paddle::framework::ir::generate_pass::VarHelper(#name)
|
|
#define OP_(type) \
|
|
::paddle::framework::ir::generate_pass::OpHelper(#type, subgraph)
|
|
#define SUBGRAPH_(name) \
|
|
::paddle::framework::ir::generate_pass::SubgraphHelper name; \
|
|
name
|
|
|
|
#define REGISTER_GENERATE_PASS(pass_type) \
|
|
paddle::framework::ir::PassPairs register_##pass_type(); \
|
|
REGISTER_PASS( \
|
|
pass_type, \
|
|
::paddle::framework::ir::MacroPassHelper<®ister_##pass_type>); \
|
|
paddle::framework::ir::PassPairs register_##pass_type()
|
|
|
|
} // namespace ir
|
|
} // namespace framework
|
|
} // namespace paddle
|