-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NewIR]Split python api and vjp #56518
Changes from all commits
4b21c66
37125f9
2c0166c
37883b2
58dd125
8834e65
d286e7f
79aa356
0cc4336
0afe2ed
00379a9
3537f91
afd61ea
d95467a
adc040f
2f3a72a
b88cc54
6b6fc8e
bfbb0e8
c428ff6
ece1b32
ff5aa2c
065c011
578e08b
0c8db6e
873ec07
7939ab2
ffc71f2
c161003
95642e3
9fcfe39
7fdb9c4
e9507d4
4d40cd6
e7ad743
ad8ea16
011c611
a20be18
185d30b
e02f612
fed29f4
add6d90
87f13b9
4ef0db1
453deed
6879097
c21b912
a3e947e
98e6beb
7dca72b
f5d60fb
47097e8
877262d
6054bde
a6b5af3
2fc525f
1072cdd
71d1c09
0ded8f3
d342f2e
5dcecd9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,5 +29,6 @@ | |
"sum", | ||
"add", | ||
"concat", | ||
"split", | ||
] | ||
vjp_interface_implementation_gen_op_list = ["tanh", "mean", "divide", "add"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
|
||
#include "paddle/fluid/ir/dialect/paddle_dialect/ir/pd_manual_op.h" | ||
#include "paddle/fluid/ir/dialect/paddle_dialect/ir/pd_attribute.h" | ||
#include "paddle/fluid/ir/dialect/paddle_dialect/ir/pd_op.h" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这里是不是可以按需 include 必要的头文件 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. splitgrad 调用了full op, 需要引入此头文件 |
||
#include "paddle/fluid/ir/dialect/paddle_dialect/ir/pd_type.h" | ||
#include "paddle/ir/core/builtin_attribute.h" | ||
#include "paddle/ir/core/builtin_op.h" | ||
|
@@ -145,7 +146,221 @@ void AddNOp::InferMeta(phi::InferMetaContext *infer_meta) { | |
fn(infer_meta); | ||
} | ||
|
||
const char *SplitGradOp::attributes_name[1] = {"axis"}; | ||
|
||
OpInfoTuple SplitGradOp::GetOpInfo() { | ||
std::vector<paddle::dialect::OpInputInfo> inputs = { | ||
OpInputInfo("out_grad", | ||
"ir::VectorType<paddle::dialect::DenseTensorType>", | ||
false, | ||
false, | ||
false), | ||
OpInputInfo( | ||
"axis", "paddle::dialect::ScalarAttribute", false, false, true)}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. axis 是可变 attribute 的话,是不是有必要添加一个axis 为Scalar类型的Build 接口? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done, 此处build接口无使用样例,存在覆盖率问题 |
||
std::vector<paddle::dialect::OpAttributeInfo> attributes = {}; | ||
std::vector<paddle::dialect::OpOutputInfo> outputs = { | ||
OpOutputInfo("x_grad", "paddle::dialect::DenseTensorType", false, false)}; | ||
paddle::dialect::OpRunTimeInfo run_time_info = | ||
OpRunTimeInfo("ConcatInferMeta", | ||
{"out_grad", "axis"}, | ||
{"concat"}, | ||
{"out_grad", "axis"}, | ||
{"out_grad"}, | ||
{}, | ||
{}, | ||
{}); | ||
|
||
return std::make_tuple( | ||
inputs, attributes, outputs, run_time_info, "split_grad"); | ||
} | ||
|
||
void SplitGradOp::Build(ir::Builder &builder, | ||
ir::OperationArgument &argument, | ||
ir::OpResult out_grad_, | ||
float axis) { | ||
// Generate scalar mutable attribute: axis | ||
paddle::dialect::FullOp full_axis_op = builder.Build<paddle::dialect::FullOp>( | ||
std::vector<int64_t>{1}, axis, phi::DataType::FLOAT32, phi::CPUPlace()); | ||
ir::OpResult axis_ = full_axis_op->result(0); | ||
|
||
VLOG(4) << "Builder construction inputs"; | ||
std::vector<ir::OpResult> argument_inputs = {out_grad_, axis_}; | ||
argument.AddOperands(argument_inputs.begin(), argument_inputs.end()); | ||
|
||
VLOG(4) << "Builder construction attributes"; | ||
|
||
VLOG(4) << "Builder construction outputs"; | ||
ir::VectorType out_grad = out_grad_.type().dyn_cast<ir::VectorType>(); | ||
std::vector<phi::DenseTensor> vec_dense_out_grad; | ||
for (size_t i = 0; i < static_cast<size_t>(out_grad.size()); i++) { | ||
vec_dense_out_grad.push_back(phi::DenseTensor( | ||
std::make_unique<paddle::experimental::DefaultAllocator>( | ||
paddle::platform::CPUPlace()) | ||
.get(), | ||
phi::DenseTensorMeta( | ||
paddle::dialect::TransToPhiDataType( | ||
out_grad[i] | ||
.dyn_cast<paddle::dialect::DenseTensorType>() | ||
.dtype()), | ||
out_grad[i].dyn_cast<paddle::dialect::DenseTensorType>().dims(), | ||
out_grad[i] | ||
.dyn_cast<paddle::dialect::DenseTensorType>() | ||
.data_layout(), | ||
out_grad[i].dyn_cast<paddle::dialect::DenseTensorType>().lod(), | ||
out_grad[i] | ||
.dyn_cast<paddle::dialect::DenseTensorType>() | ||
.offset()))); | ||
} | ||
std::vector<phi::MetaTensor> vec_meta_out_grad; | ||
for (size_t i = 0; i < vec_dense_out_grad.size(); i++) { | ||
vec_meta_out_grad.push_back(phi::MetaTensor(&vec_dense_out_grad[i])); | ||
} | ||
|
||
std::vector<const phi::MetaTensor *> meta_out_grad; | ||
for (size_t i = 0; i < static_cast<size_t>(vec_meta_out_grad.size()); i++) { | ||
meta_out_grad.push_back(&vec_meta_out_grad[i]); | ||
} | ||
phi::DenseTensor dense_x_grad; | ||
phi::MetaTensor meta_x_grad(&dense_x_grad); | ||
|
||
phi::ConcatInferMeta(meta_out_grad, axis, &meta_x_grad); | ||
|
||
std::vector<ir::Type> argument_outputs; | ||
ir::Type x_grad_dense_tensor_type = paddle::dialect::DenseTensorType::get( | ||
ir::IrContext::Instance(), | ||
paddle::dialect::TransToIrDataType(dense_x_grad.dtype()), | ||
dense_x_grad.dims(), | ||
dense_x_grad.layout(), | ||
dense_x_grad.lod(), | ||
dense_x_grad.offset()); | ||
argument_outputs.push_back(x_grad_dense_tensor_type); | ||
argument.AddOutputs(argument_outputs.begin(), argument_outputs.end()); | ||
} | ||
|
||
void SplitGradOp::Build(ir::Builder &builder, | ||
ir::OperationArgument &argument, | ||
ir::OpResult out_grad_, | ||
ir::OpResult axis_) { | ||
VLOG(4) << "Builder construction inputs"; | ||
std::vector<ir::OpResult> argument_inputs = {out_grad_, axis_}; | ||
argument.AddOperands(argument_inputs.begin(), argument_inputs.end()); | ||
|
||
VLOG(4) << "Builder construction attributes"; | ||
|
||
VLOG(4) << "Builder construction outputs"; | ||
ir::VectorType out_grad = out_grad_.type().dyn_cast<ir::VectorType>(); | ||
int axis = axis_.owner() | ||
->dyn_cast<paddle::dialect::FullOp>() | ||
.attributes() | ||
.at("value") | ||
.dyn_cast<paddle::dialect::ScalarAttribute>() | ||
.data() | ||
.to<int>(); | ||
|
||
std::vector<phi::DenseTensor> vec_dense_out_grad; | ||
for (size_t i = 0; i < static_cast<size_t>(out_grad.size()); i++) { | ||
vec_dense_out_grad.push_back(phi::DenseTensor( | ||
std::make_unique<paddle::experimental::DefaultAllocator>( | ||
paddle::platform::CPUPlace()) | ||
.get(), | ||
phi::DenseTensorMeta( | ||
TransToPhiDataType(out_grad[i] | ||
.dyn_cast<paddle::dialect::DenseTensorType>() | ||
.dtype()), | ||
out_grad[i].dyn_cast<paddle::dialect::DenseTensorType>().dims(), | ||
out_grad[i] | ||
.dyn_cast<paddle::dialect::DenseTensorType>() | ||
.data_layout(), | ||
out_grad[i].dyn_cast<paddle::dialect::DenseTensorType>().lod(), | ||
out_grad[i] | ||
.dyn_cast<paddle::dialect::DenseTensorType>() | ||
.offset()))); | ||
} | ||
std::vector<phi::MetaTensor> vec_meta_out_grad; | ||
for (size_t i = 0; i < vec_dense_out_grad.size(); i++) { | ||
vec_meta_out_grad.push_back(phi::MetaTensor(&vec_dense_out_grad[i])); | ||
} | ||
|
||
std::vector<const phi::MetaTensor *> meta_out_grad; | ||
for (size_t i = 0; i < static_cast<size_t>(vec_meta_out_grad.size()); i++) { | ||
meta_out_grad.push_back(&vec_meta_out_grad[i]); | ||
} | ||
phi::DenseTensor dense_x_grad; | ||
phi::MetaTensor meta_x_grad(&dense_x_grad); | ||
|
||
phi::ConcatInferMeta(meta_out_grad, axis, &meta_x_grad); | ||
|
||
std::vector<ir::Type> argument_outputs; | ||
ir::Type x_grad_dense_tensor_type = paddle::dialect::DenseTensorType::get( | ||
ir::IrContext::Instance(), | ||
TransToIrDataType(dense_x_grad.dtype()), | ||
dense_x_grad.dims(), | ||
dense_x_grad.layout(), | ||
dense_x_grad.lod(), | ||
dense_x_grad.offset()); | ||
argument_outputs.push_back(x_grad_dense_tensor_type); | ||
argument.AddOutputs(argument_outputs.begin(), argument_outputs.end()); | ||
} | ||
|
||
void SplitGradOp::Verify() { | ||
VLOG(4) << "Start Verifying inputs, outputs and attributes for: SplitGradOp."; | ||
VLOG(4) << "Verifying inputs:"; | ||
{ | ||
auto input_size = num_operands(); | ||
PADDLE_ENFORCE_EQ( | ||
input_size, | ||
2u, | ||
phi::errors::PreconditionNotMet( | ||
"The size %d of inputs must be equal to 2.", input_size)); | ||
if (auto vec_type = | ||
(*this)->operand_source(0).type().dyn_cast<ir::VectorType>()) { | ||
for (size_t i = 0; i < vec_type.size(); ++i) { | ||
PADDLE_ENFORCE(vec_type[i].isa<paddle::dialect::DenseTensorType>(), | ||
phi::errors::PreconditionNotMet( | ||
"Type validation failed for the 0th input.")); | ||
} | ||
} else { | ||
PADDLE_ENFORCE((*this) | ||
->operand_source(0) | ||
.type() | ||
.isa<paddle::dialect::DenseTensorType>(), | ||
phi::errors::PreconditionNotMet( | ||
"Type validation failed for the 0th input.")); | ||
} | ||
PADDLE_ENFORCE((*this) | ||
->operand_source(1) | ||
.type() | ||
.isa<paddle::dialect::DenseTensorType>(), | ||
phi::errors::PreconditionNotMet( | ||
"Type validation failed for the 1th input.")); | ||
} | ||
VLOG(4) << "Verifying attributes:"; | ||
{ | ||
// Attributes num is 0, not need to check attributes type. | ||
} | ||
VLOG(4) << "Verifying outputs:"; | ||
{ | ||
auto output_size = num_results(); | ||
PADDLE_ENFORCE_EQ( | ||
output_size, | ||
1u, | ||
phi::errors::PreconditionNotMet( | ||
"The size %d of outputs must be equal to 1.", output_size)); | ||
PADDLE_ENFORCE( | ||
(*this)->result(0).type().isa<paddle::dialect::DenseTensorType>(), | ||
phi::errors::PreconditionNotMet( | ||
"Type validation failed for the 0th output.")); | ||
} | ||
VLOG(4) << "End Verifying for: SplitGradOp."; | ||
} | ||
|
||
void SplitGradOp::InferMeta(phi::InferMetaContext *infer_meta) { | ||
auto fn = PD_INFER_META(phi::ConcatInferMeta); | ||
fn(infer_meta); | ||
} | ||
|
||
} // namespace dialect | ||
} // namespace paddle | ||
|
||
IR_DEFINE_EXPLICIT_TYPE_ID(paddle::dialect::AddNOp) | ||
IR_DEFINE_EXPLICIT_TYPE_ID(paddle::dialect::SplitGradOp) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,7 @@ | |
|
||
#ifdef GET_MANUAL_OP_LIST | ||
#undef GET_MANUAL_OP_LIST | ||
paddle::dialect::AddNOp | ||
paddle::dialect::AddNOp, paddle::dialect::SplitGradOp | ||
|
||
#else | ||
|
||
|
@@ -51,9 +51,33 @@ class AddNOp : public ir::Op<AddNOp, OpYamlInfoInterface> { | |
static void InferMeta(phi::InferMetaContext *infer_meta); | ||
}; | ||
|
||
class SplitGradOp : public ir::Op<SplitGradOp, OpYamlInfoInterface> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 是不需要有 paddle::dialect::InferMetaInterface 接口么?我看pd_op.h 里其他的GradOp 都是有的 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个splitgrad yaml 中没有infermeta, 使用的是invoke算子concat 的infermeta, 已补充 |
||
public: | ||
using Op::Op; | ||
static const char *name() { return "pd.split_grad"; } | ||
static const char *attributes_name[1]; | ||
static constexpr uint32_t attributes_num = 1; | ||
static OpInfoTuple GetOpInfo(); | ||
static void Build(ir::Builder &builder, // NOLINT | ||
ir::OperationArgument &argument, // NOLINT | ||
ir::OpResult x_, | ||
float axis = 0); | ||
static void Build(ir::Builder &builder, // NOLINT | ||
ir::OperationArgument &argument, // NOLINT | ||
ir::OpResult out_grad_, | ||
ir::OpResult axis_); | ||
|
||
void Verify(); | ||
ir::Value out_grad() { return operand_source(0); } | ||
ir::Value axis() { return operand_source(1); } | ||
ir::OpResult x_grad() { return result(0); } | ||
static void InferMeta(phi::InferMetaContext *infer_meta); | ||
}; | ||
|
||
} // namespace dialect | ||
} // namespace paddle | ||
|
||
IR_DECLARE_EXPLICIT_TYPE_ID(paddle::dialect::AddNOp) | ||
IR_DECLARE_EXPLICIT_TYPE_ID(paddle::dialect::SplitGradOp) | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@0x45f 我看 pd_api.h 里的 concat、add_n 的vector 入参也是值copy,这个是不是可以优化为 const &?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个在build 函数手写完备后,可加入自动代码生成一起完善