Skip to content

Commit

Permalink
add op builder for canonicalization (PaddlePaddle#57)
Browse files Browse the repository at this point in the history
* use new pow_handler
  • Loading branch information
gglin001 authored Aug 13, 2021
1 parent 77f9be7 commit c054e1c
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 46 deletions.
1 change: 1 addition & 0 deletions paddle/fluid/framework/ipu/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
set(POPART_CANONICALIZATION_SRC
"popart_canonicalization/canonicalization_utils.cc"
"popart_canonicalization/op_builder.cc"
"popart_canonicalization/activation_ops.cc"
"popart_canonicalization/logic_ops.cc"
"popart_canonicalization/math_ops.cc"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,21 @@ void MoveNodeInputs(ir::Node *node, ir::Node *new_node) {
}
}

void ReplaceNodeInputs(ir::Node *node, ir::Node *new_node) {
if (node->inputs.empty()) {
return;
}
new_node->inputs = node->inputs;
for (auto *node_in : node->inputs) {
for (size_t i = 0; i < node_in->outputs.size(); ++i) {
if (node_in->outputs[i] == node) {
node_in->outputs[i] = new_node;
break;
}
}
}
}

void MoveNodeOutputs(ir::Node *node, ir::Node *new_node) {
if (node->outputs.empty()) {
return;
Expand All @@ -74,12 +89,26 @@ void MoveNodeOutputs(ir::Node *node, ir::Node *new_node) {
}
}

void ReplaceNodeOutputs(ir::Node *node, ir::Node *new_node) {
if (node->outputs.empty()) {
return;
}
for (auto *node_out : node->outputs) {
for (size_t i = 0; i < node_out->inputs.size(); ++i) {
if (node_out->inputs[i] == node) {
node_out->inputs[i] = new_node;
break;
}
}
}
}

void ConnectNodes(ir::Node *first_node, ir::Node *next_node) {
first_node->outputs.push_back(next_node);
next_node->inputs.push_back(first_node);
}

void CopyOpAttr(std::string attr_name, OpDesc *op, OpDesc *new_op,
void CopyOpAttr(const std::string &attr_name, OpDesc *op, OpDesc *new_op,
bool override) {
if (new_op->HasAttr(attr_name) && !override) {
return;
Expand All @@ -90,7 +119,7 @@ void CopyOpAttr(std::string attr_name, OpDesc *op, OpDesc *new_op,
}
}

int ConvertDataType(int type) {
const int ConvertDataType(const int &type) {
auto dtype = static_cast<proto::VarType::Type>(type);
switch (dtype) {
case proto::VarType::BOOL:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@

#pragma once

#include <functional>
#include <string>
#include <vector>

#include "paddle/fluid/framework/ipu/ipu_utils.h"
#include "paddle/fluid/framework/ir/graph.h"
#include "paddle/fluid/framework/ir/node.h"
Expand All @@ -39,13 +35,17 @@ bool RegisterHandler(const std::string &, const SymbolHandler &);

SymbolHandler GetHandler(const std::string &);

// TODO(alleng) remove these func
void MoveNodeInputs(ir::Node *node, ir::Node *new_node);
void MoveNodeOutputs(ir::Node *node, ir::Node *new_node);

void ReplaceNodeInputs(ir::Node *node, ir::Node *new_node);
void ReplaceNodeOutputs(ir::Node *node, ir::Node *new_node);
void ConnectNodes(ir::Node *first_node, ir::Node *next_node);
void CopyOpAttr(std::string attr_name, OpDesc *op, OpDesc *new_op,
void CopyOpAttr(const std::string &attr_name, OpDesc *op, OpDesc *new_op,
bool override = false);

int ConvertDataType(int);
const int ConvertDataType(const int &type);

} // namespace ipu
} // namespace framework
Expand Down
48 changes: 10 additions & 38 deletions paddle/fluid/framework/ipu/popart_canonicalization/math_ops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

#include "paddle/fluid/framework/ipu/popart_canonicalization/canonicalization_utils.h"
#include "paddle/fluid/framework/ipu/popart_canonicalization/op_builder.h"
#include "paddle/fluid/platform/enforce.h"

namespace paddle {
Expand Down Expand Up @@ -65,45 +66,16 @@ ir::Node *reduce_mean_handler(ir::Graph *graph, ir::Node *node) {
ir::Node *pow_handler(ir::Graph *graph, ir::Node *node) {
// Op(pow) -> Op(Constant)->Var(const_out)->Op(Pow)
auto *op = node->Op();
// Op(Constant)
auto op_const = std::make_unique<framework::OpDesc>();
op_const->SetType("Constant");
std::string op_const_out = op->Output("Out").front() + ":__0_";
auto value_ = BOOST_GET_CONST(float, op->GetAttr("factor"));
auto value = std::vector<float>{value_};
op_const->SetAttr("value", value);
auto dims = std::vector<int64_t>{1};
op_const->SetAttr("dims", dims);
op_const->SetAttr("dtype", ONNXDataType::FLOAT);
std::vector<std::string> outputs_const;
outputs_const.push_back(op_const_out);
op_const->SetOutput("__outputs__", outputs_const);
op_const->Flush();
// Var(const_out)
auto var_const = std::make_unique<framework::VarDesc>(op_const_out);
var_const->SetType(proto::VarType::LOD_TENSOR);
var_const->SetDataType(proto::VarType::FP32);
auto shape_var_const = std::vector<int64_t>{1};
var_const->SetShape(shape_var_const);
auto var_node_const = graph->CreateVarNode(var_const.get());
auto node_const = graph->CreateOpNode(op_const.get());
MoveNodeInputs(node, node_const);
ConnectNodes(node_const, var_node_const);
// Op(Pow)
auto op_pow = std::make_unique<framework::OpDesc>();
op_pow->SetType("Pow");
std::vector<std::string> inputs;
inputs.push_back(op->Input("X").front());
inputs.push_back(op_const->Output("__outputs__").front());
op_pow->SetInput("__inputs__", inputs);
std::vector<std::string> outputs;
outputs.push_back(op->Output("Out").front());
op_pow->SetOutput("__outputs__", outputs);
op_pow->Flush();
auto node_pow = graph->CreateOpNode(op_pow.get());
ConnectNodes(var_node_const, node_pow);
MoveNodeOutputs(node, node_pow);
return node_pow;
auto attrs = MakeConstAttributeMap(value_, {1}, ONNXDataType::FLOAT);
auto new_node_const = CreateConst(graph, {node}, {}, attrs);
ReplaceNodeOutputs(node, new_node_const);

auto new_node_pow =
CreatePow(graph, {node->inputs[0], new_node_const->outputs[0]},
{node->outputs[0]}, {});
ReplaceNodeInputs(node, new_node_pow);
return new_node_pow;
}

ir::Node *mul_handler(ir::Graph *graph, ir::Node *node) {
Expand Down
102 changes: 102 additions & 0 deletions paddle/fluid/framework/ipu/popart_canonicalization/op_builder.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// 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.

#include "paddle/fluid/framework/ipu/popart_canonicalization/op_builder.h"

#include "paddle/fluid/framework/ipu/popart_canonicalization/canonicalization_utils.h"

namespace paddle {
namespace framework {
namespace ipu {

// singleton
static int var_count = 0;

std::string GenerateVarName() {
return std::string("_popart_gen_") + std::to_string(var_count++);
}

ir::Node *MakeVarNode(ir::Graph *graph) {
auto var_name = GenerateVarName();
auto var_desc = std::make_unique<framework::VarDesc>(var_name);

auto var = graph->CreateVarNode(var_desc.get());
return var;
}

ir::Node *MakeOpNode(ir::Graph *graph, const std::string &type,
const std::vector<ir::Node *> &inputs,
const std::vector<ir::Node *> &outputs) {
auto op_desc = std::make_unique<framework::OpDesc>();
op_desc->SetType(type);
auto op = graph->CreateOpNode(op_desc.get());

for (auto *in : inputs) {
ConnectNodes(in, op);
}
if (outputs.empty()) {
auto var = MakeVarNode(graph);
ConnectNodes(op, var);
} else {
for (auto *out : outputs) {
ConnectNodes(op, out);
}
}

// i/o
std::vector<std::string> input_names;
for (auto node : op->inputs) {
input_names.push_back(node->Name());
}
op->Op()->SetInput("__inputs__", input_names);
std::vector<std::string> output_names;
for (auto node : op->outputs) {
output_names.push_back(node->Name());
}
op->Op()->SetOutput("__outputs__", output_names);
op->Op()->Flush();

return op;
}

AttributeMap MakeConstAttributeMap(float v, std::vector<int64_t> dims,
int dtype) {
size_t size = 1;
for (auto &dim : dims) {
size *= dim;
}
std::vector<float> value(size, v);
return AttributeMap{
{"value", value}, {"dims", dims}, {"dtype", dtype},
};
}

ir::Node *CreateConst(ir::Graph *graph, const std::vector<ir::Node *> &inputs,
const std::vector<ir::Node *> &outputs,
const AttributeMap &attrs) {
auto node = MakeOpNode(graph, "Constant", {}, {});
node->Op()->SetAttrMap(attrs);
return node;
}

ir::Node *CreatePow(ir::Graph *graph, const std::vector<ir::Node *> &inputs,
const std::vector<ir::Node *> &outputs,
const AttributeMap &attrs) {
auto node = MakeOpNode(graph, "Pow", inputs, outputs);
return node;
}

} // namespace ipu
} // namespace framework
} // namespace paddle
43 changes: 43 additions & 0 deletions paddle/fluid/framework/ipu/popart_canonicalization/op_builder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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/ipu/popart_canonicalization/canonicalization_utils.h"

namespace paddle {
namespace framework {
namespace ipu {

std::string GenerateVarName();

ir::Node *MakeVarNode(ir::Graph *graph);
ir::Node *MakeOpNode(ir::Graph *graph, const std::string &type,
const std::vector<ir::Node *> &inputs,
const std::vector<ir::Node *> &outputs);

// TODO(alleng) make template
AttributeMap MakeConstAttributeMap(float v, std::vector<int64_t> dims,
int dtype);
ir::Node *CreateConst(ir::Graph *graph, const std::vector<ir::Node *> &inputs,
const std::vector<ir::Node *> &outputs,
const AttributeMap &attrs);

ir::Node *CreatePow(ir::Graph *graph, const std::vector<ir::Node *> &inputs,
const std::vector<ir::Node *> &outputs,
const AttributeMap &attrs);

} // namespace ipu
} // namespace framework
} // namespace paddle

0 comments on commit c054e1c

Please sign in to comment.