| 2456 | } |
| 2457 | |
| 2458 | void OperatorWithKernel::HandleComplexGradToRealGrad( |
| 2459 | const Scope& scope, RuntimeContext* ctx) const { |
| 2460 | for (auto& var_name_item : Outputs()) { |
| 2461 | std::vector<Variable*>& output_vars = ctx->outputs[var_name_item.first]; |
| 2462 | for (size_t i = 0; i < var_name_item.second.size(); ++i) { |
| 2463 | // 1. find grad_var & check whether is complex tensor |
| 2464 | auto var_name = var_name_item.second[i]; |
| 2465 | auto orig_var_name = GradOriginalVarName(var_name); |
| 2466 | // only focus on gradient var |
| 2467 | if (var_name == orig_var_name) { |
| 2468 | continue; |
| 2469 | } |
| 2470 | auto* grad_var = output_vars[i]; |
| 2471 | // skip nullptr var |
| 2472 | if (grad_var == nullptr) { |
| 2473 | continue; |
| 2474 | } |
| 2475 | // don't process phi::TensorArray temporarily, |
| 2476 | // add support if necessary for complex number calculations in the future |
| 2477 | if (!VarIsTensor(*grad_var)) { |
| 2478 | continue; |
| 2479 | } |
| 2480 | auto* grad_tensor = |
| 2481 | GetMutableDenseTensorOrSelectedRowsValueFromVar(grad_var); |
| 2482 | // skip nullptr tensor |
| 2483 | if (grad_tensor == nullptr || !grad_tensor->IsInitialized()) { |
| 2484 | continue; |
| 2485 | } |
| 2486 | // only focus on complex dtype now |
| 2487 | auto src_type = framework::TransToProtoVarType(grad_tensor->dtype()); |
| 2488 | if (!IsComplexType(src_type)) { |
| 2489 | continue; |
| 2490 | } |
| 2491 | |
| 2492 | // 2. find forward var & check whether need to cast |
| 2493 | auto* var = scope.FindVar(orig_var_name); |
| 2494 | // if forward var not exists, do nothing |
| 2495 | if (var == nullptr) { |
| 2496 | continue; |
| 2497 | } |
| 2498 | if (!VarIsTensor(*var)) { |
| 2499 | continue; |
| 2500 | } |
| 2501 | const auto* tensor = GetDenseTensorOrSelectedRowsValueFromVar(*var); |
| 2502 | PADDLE_ENFORCE_NOT_NULL( |
| 2503 | tensor, |
| 2504 | common::errors::Unavailable( |
| 2505 | "Forward tensor is nullptr when handle complex data to real.")); |
| 2506 | // only need record type, the allocation may have been released |
| 2507 | auto dst_type = framework::TransToProtoVarType(tensor->dtype()); |
| 2508 | // only focus on real dtype and need casting |
| 2509 | if (IsComplexType(dst_type)) { |
| 2510 | continue; |
| 2511 | } |
| 2512 | |
| 2513 | // 3. cast complex grad to real grad |
| 2514 | VLOG(6) << "Transform " << framework::DataTypeToString(src_type) |
| 2515 | << " var `" << var_name << "` to " |
nothing calls this directly
no test coverage detected