未验证 提交 462ae005 编写于 作者: W wanghuancoder 提交者: GitHub

[Eager] Fix Full Zero (#43048)

* fix full zero

* fix full zero

* fix full zero

* fix full zero

* refine

* refine

* refine
上级 d70e45bc
...@@ -2043,6 +2043,32 @@ static std::string GenerateSingleOpBase( ...@@ -2043,6 +2043,32 @@ static std::string GenerateSingleOpBase(
const std::string& ins_name = "ins" + std::to_string(*outs_size); const std::string& ins_name = "ins" + std::to_string(*outs_size);
const std::string& outs_name = "outs" + std::to_string(*outs_size); const std::string& outs_name = "outs" + std::to_string(*outs_size);
const std::string& attrs_name = "attrs_map" + std::to_string(*outs_size); const std::string& attrs_name = "attrs_map" + std::to_string(*outs_size);
const std::string& hooked_grads = "hooked_grads" + std::to_string(*outs_size);
// [Generation] Get Full Zero
std::string fill_zero_str = "";
if (ops_to_fill_zero_for_empty_grads.count(fwd_op_type)) {
for (auto iter : grad_ins) {
const std::string& grad_input_name = iter.first;
if (grad_ins_grad_slotname_map.count(grad_input_name)) {
size_t fwd_output_position = fwd_outputs_name_pos_map.at(
grad_ins_grad_slotname_map.at(grad_input_name));
const char* FILL_ZERO_TEMPLATE =
"egr::EagerUtils::FillZeroForEmptyOptionalGradInput(&grads[%d], "
"this->InputMeta()[%d]);\n";
fill_zero_str += paddle::string::Sprintf(
FILL_ZERO_TEMPLATE, fwd_output_position, fwd_output_position);
}
}
}
generated_grad_function_body += fill_zero_str;
generated_grad_function_body +=
" paddle::small_vector<std::vector<paddle::experimental::Tensor>, "
"egr::kSlotSmallVectorSize> " +
hooked_grads +
" = "
"GradNode" +
fwd_op_type + "::ApplyGradientHooks(grads);\n";
// [Generation] Get Ins Map // [Generation] Get Ins Map
std::unordered_set<std::string> dispensable_input_name_set; std::unordered_set<std::string> dispensable_input_name_set;
...@@ -2117,16 +2143,16 @@ static std::string GenerateSingleOpBase( ...@@ -2117,16 +2143,16 @@ static std::string GenerateSingleOpBase(
size_t fwd_output_position = fwd_outputs_name_pos_map.at( size_t fwd_output_position = fwd_outputs_name_pos_map.at(
grad_ins_grad_slotname_map.at(grad_input_name)); grad_ins_grad_slotname_map.at(grad_input_name));
const char* GRAD_INS_GRAD_CONTENT_TEMPLATE = const char* GRAD_INS_GRAD_CONTENT_TEMPLATE =
"{ \"%s\", egr::EagerUtils::TrySyncToVars(hooked_grads[%d]) },"; "{ \"%s\", egr::EagerUtils::TrySyncToVars(%s[%d]) },";
ins_contents_str += paddle::string::Sprintf( ins_contents_str += paddle::string::Sprintf(
GRAD_INS_GRAD_CONTENT_TEMPLATE, grad_input_name, fwd_output_position); GRAD_INS_GRAD_CONTENT_TEMPLATE, grad_input_name, hooked_grads,
fwd_output_position);
if (!backward_inplace_map.empty() && if (!backward_inplace_map.empty() &&
backward_inplace_map.count(grad_input_name)) { backward_inplace_map.count(grad_input_name)) {
process_backward_inplace = true; process_backward_inplace = true;
const char* GRAD_INS_HOOKED_GRAD_TEMPLATE = const char* GRAD_INS_HOOKED_GRAD_TEMPLATE = "auto& %s = %s[%d][0];";
"auto& %s = hooked_grads[%d][0];";
std::string hooked_grads_tensor_str = paddle::string::Sprintf( std::string hooked_grads_tensor_str = paddle::string::Sprintf(
GRAD_INS_HOOKED_GRAD_TEMPLATE, bwd_inplace_input_name, GRAD_INS_HOOKED_GRAD_TEMPLATE, bwd_inplace_input_name, hooked_grads,
fwd_output_position); fwd_output_position);
const char* GRAD_INS_GRAD_TENSOR_TEMPLATE = "grads[%d][0]"; const char* GRAD_INS_GRAD_TENSOR_TEMPLATE = "grads[%d][0]";
std::string grads_tensor_str = paddle::string::Sprintf( std::string grads_tensor_str = paddle::string::Sprintf(
...@@ -2239,10 +2265,10 @@ static std::string GenerateSingleOpBase( ...@@ -2239,10 +2265,10 @@ static std::string GenerateSingleOpBase(
const char* GRAD_OUTS_CONTENT_TEMPLATE = const char* GRAD_OUTS_CONTENT_TEMPLATE =
" if((!out_metas[%d].empty()) && " " if((!out_metas[%d].empty()) && "
"(!(out_metas[%d][0].IsStopGradient()))){ \n %s.insert({ \"%s\", " "(!(out_metas[%d][0].IsStopGradient()))){ \n %s.insert({ \"%s\", "
"egr::EagerUtils::TrySyncToVars(hooked_grads[%d])});} \n "; "egr::EagerUtils::TrySyncToVars(%s[%d])});} \n ";
outs_contents_str += paddle::string::Sprintf( outs_contents_str += paddle::string::Sprintf(
GRAD_OUTS_CONTENT_TEMPLATE, grads_position, grads_position, GRAD_OUTS_CONTENT_TEMPLATE, grads_position, grads_position,
outs_name, grad_output_name, grads_position); outs_name, grad_output_name, hooked_grads, grads_position);
} else { } else {
if (dispensable_input_name_set.count(fwd_name) && if (dispensable_input_name_set.count(fwd_name) &&
...@@ -2561,9 +2587,6 @@ static std::string GenerateGradNodeCCContents( ...@@ -2561,9 +2587,6 @@ static std::string GenerateGradNodeCCContents(
} }
const char* BWD_RETURN_TEMPLATE = const char* BWD_RETURN_TEMPLATE =
" paddle::small_vector<std::vector<paddle::experimental::Tensor>, "
"egr::kSlotSmallVectorSize> hooked_grads = "
"GradNode%s::ApplyGradientHooks(grads);\n"
" const auto& out_metas = OutputMeta();\n" " const auto& out_metas = OutputMeta();\n"
" paddle::small_vector<std::vector<paddle::experimental::Tensor>, " " paddle::small_vector<std::vector<paddle::experimental::Tensor>, "
"egr::kSlotSmallVectorSize> outputs(%d);\n" "egr::kSlotSmallVectorSize> outputs(%d);\n"
...@@ -2571,9 +2594,8 @@ static std::string GenerateGradNodeCCContents( ...@@ -2571,9 +2594,8 @@ static std::string GenerateGradNodeCCContents(
" if(NeedComplexToRealConversion()) " " if(NeedComplexToRealConversion()) "
"HandleComplexGradToRealGrad(&outputs);\n" "HandleComplexGradToRealGrad(&outputs);\n"
" return outputs;\n"; " return outputs;\n";
generated_grad_function_body = generated_grad_function_body = paddle::string::Sprintf(
paddle::string::Sprintf(BWD_RETURN_TEMPLATE, fwd_op_type, in_vars.size(), BWD_RETURN_TEMPLATE, in_vars.size(), generated_grad_function_body);
generated_grad_function_body);
// [Generation] Get Full Grad Function // [Generation] Get Full Grad Function
const char* GRAD_FUNCTION_TEMPLATE = const char* GRAD_FUNCTION_TEMPLATE =
...@@ -2584,17 +2606,9 @@ static std::string GenerateGradNodeCCContents( ...@@ -2584,17 +2606,9 @@ static std::string GenerateGradNodeCCContents(
"egr::kSlotSmallVectorSize>& grads, bool " "egr::kSlotSmallVectorSize>& grads, bool "
"create_graph, bool is_new_grad) {\n" "create_graph, bool is_new_grad) {\n"
"%s" "%s"
"%s"
"\n}"; "\n}";
std::string fill_zero_str = ""; std::string grad_function_str = paddle::string::Sprintf(
if (ops_to_fill_zero_for_empty_grads.count(fwd_op_type)) { GRAD_FUNCTION_TEMPLATE, fwd_op_type, generated_grad_function_body);
fill_zero_str =
"egr::EagerUtils::FillZeroForEmptyGradInputs(&grads, "
"this->InputMeta());\n";
}
std::string grad_function_str =
paddle::string::Sprintf(GRAD_FUNCTION_TEMPLATE, fwd_op_type,
fill_zero_str, generated_grad_function_body);
VLOG(6) << "Generated returns"; VLOG(6) << "Generated returns";
......
...@@ -250,7 +250,7 @@ TEST(EagerUtils, GetGradAccumulationNode) { ...@@ -250,7 +250,7 @@ TEST(EagerUtils, GetGradAccumulationNode) {
ASSERT_ANY_THROW(egr::EagerUtils::GetGradAccumulationNode(t0)); ASSERT_ANY_THROW(egr::EagerUtils::GetGradAccumulationNode(t0));
} }
TEST(EagerUtils, FillZeroForEmptyGradInputs) { TEST(EagerUtils, FillZeroForEmptyOptionalGradInput) {
paddle::small_vector<std::vector<paddle::experimental::Tensor>, paddle::small_vector<std::vector<paddle::experimental::Tensor>,
egr::kSlotSmallVectorSize> egr::kSlotSmallVectorSize>
grads = {std::vector<paddle::experimental::Tensor>(1)}; grads = {std::vector<paddle::experimental::Tensor>(1)};
...@@ -263,7 +263,7 @@ TEST(EagerUtils, FillZeroForEmptyGradInputs) { ...@@ -263,7 +263,7 @@ TEST(EagerUtils, FillZeroForEmptyGradInputs) {
slot_metas[0][0].SetTensorMeta(tensor_meta); slot_metas[0][0].SetTensorMeta(tensor_meta);
slot_metas[0][0].SetPlace(phi::CPUPlace()); slot_metas[0][0].SetPlace(phi::CPUPlace());
EagerUtils::FillZeroForEmptyGradInputs(&grads, slot_metas); EagerUtils::FillZeroForEmptyOptionalGradInput(&grads[0], slot_metas[0]);
eager_test::CompareTensorWithValue<float>(grads[0][0], 0.0); eager_test::CompareTensorWithValue<float>(grads[0][0], 0.0);
} }
......
...@@ -379,8 +379,8 @@ class GradNodeRunProgram : public egr::GradNodeBase { ...@@ -379,8 +379,8 @@ class GradNodeRunProgram : public egr::GradNodeBase {
"The hooked_grads.size() of RunProgramGradOp should " "The hooked_grads.size() of RunProgramGradOp should "
"be equal to 1.")); "be equal to 1."));
egr::EagerUtils::FillZeroForEmptyGradInputs(&hooked_grads, egr::EagerUtils::FillZeroForEmptyOptionalGradInput(&hooked_grads[0],
this->InputMeta()); this->InputMeta()[0]);
VLOG(3) << "hooked_grads[0].size() : " << hooked_grads[0].size(); VLOG(3) << "hooked_grads[0].size() : " << hooked_grads[0].size();
std::vector<paddle::experimental::Tensor> x_grad; std::vector<paddle::experimental::Tensor> x_grad;
std::vector<paddle::experimental::Tensor> params_grad; std::vector<paddle::experimental::Tensor> params_grad;
......
...@@ -467,26 +467,16 @@ std::shared_ptr<egr::GradNodeBase> EagerUtils::GetGradAccumulationNode( ...@@ -467,26 +467,16 @@ std::shared_ptr<egr::GradNodeBase> EagerUtils::GetGradAccumulationNode(
} }
} }
void EagerUtils::FillZeroForEmptyGradInputs( void EagerUtils::FillZeroForEmptyOptionalGradInput(
paddle::small_vector<std::vector<paddle::experimental::Tensor>, std::vector<paddle::experimental::Tensor>* in_grads,
kSlotSmallVectorSize>* in_grads, const std::vector<GradSlotMeta>& grad_in_metas) {
const paddle::small_vector<std::vector<GradSlotMeta>, kSlotSmallVectorSize>&
grad_in_metas) {
for (size_t i = 0; i < in_grads->size(); i++) { for (size_t i = 0; i < in_grads->size(); i++) {
for (size_t j = 0; j < (*in_grads)[i].size(); j++) { paddle::experimental::Tensor& grad = (*in_grads)[i];
paddle::experimental::Tensor& grad = (*in_grads)[i][j]; if (!grad.initialized() && grad_in_metas[i].HasTensorMeta()) {
if (!grad.initialized()) { auto tensor_with_zero = paddle::experimental::full(
const GradSlotMeta& grad_in_meta = grad_in_metas[i][j]; phi::vectorize(grad_in_metas[i].GetTensorMeta().dims), 0.0,
PADDLE_ENFORCE( grad_in_metas[i].GetTensorMeta().dtype, grad_in_metas[i].GetPlace());
grad_in_meta.HasTensorMeta(), grad.set_impl(tensor_with_zero.impl());
paddle::platform::errors::Fatal(
"Unable to fill empty grad inputs due to empty GradSlotMeta"));
const auto& tensor_meta = grad_in_meta.GetTensorMeta();
auto tensor_with_zero = paddle::experimental::full(
phi::vectorize(tensor_meta.dims), 0.0, tensor_meta.dtype,
grad_in_meta.GetPlace());
grad.set_impl(tensor_with_zero.impl());
}
} }
} }
} }
......
...@@ -236,11 +236,9 @@ class EagerUtils { ...@@ -236,11 +236,9 @@ class EagerUtils {
/** /**
* Fill Zero * Fill Zero
* **/ * **/
static void FillZeroForEmptyGradInputs( static void FillZeroForEmptyOptionalGradInput(
paddle::small_vector<std::vector<paddle::experimental::Tensor>, std::vector<paddle::experimental::Tensor>* in_grads,
kSlotSmallVectorSize>* out_grads, const std::vector<GradSlotMeta>& grad_in_metas);
const paddle::small_vector<std::vector<GradSlotMeta>,
kSlotSmallVectorSize>& grad_out_metas);
static void FillZeroForEmptyGradInput(paddle::experimental::Tensor* in_grad, static void FillZeroForEmptyGradInput(paddle::experimental::Tensor* in_grad,
const GradSlotMeta& grad_in_meta); const GradSlotMeta& grad_in_meta);
static void FillZeroForEmptyOptionalGradInput( static void FillZeroForEmptyOptionalGradInput(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册