| 84 | } |
| 85 | |
| 86 | void ExpandVirtualGradPass::apply(OptState& opt) const { |
| 87 | MIDOUT_B("ExpandVirtualGradPass::apply") |
| 88 | #if MGB_ENABLE_GRAD |
| 89 | opt.set_var_replace_check_flag(VarReplaceCheckFlag::NOCHECK); |
| 90 | auto rewriter = opt.graph().make_rewriter(); |
| 91 | auto on_opr = [&](OperatorNodeBase* opr) { |
| 92 | if (!opr->same_type<opr::VirtualGrad>()) { |
| 93 | rewriter.auto_replace_outputs(opr); |
| 94 | return; |
| 95 | } |
| 96 | // Create opr and replace var but no need to copy old opr_properties |
| 97 | // to new oprs because grad_manager would handle it. |
| 98 | opt.call_with_opr( |
| 99 | opr, |
| 100 | [&] { |
| 101 | auto target = opr->input(0), wrt = opr->input(1), |
| 102 | grad = cg::grad(target, wrt).node(); |
| 103 | auto src = opr->output(0); |
| 104 | grad = GraphOptimizer::var_replace_lookup(grad); |
| 105 | rewriter.replace_var( |
| 106 | src, grad, |
| 107 | mgb_ssprintf_log( |
| 108 | "grad(%s, %s)", target->cname(), wrt->cname()) |
| 109 | .c_str()); |
| 110 | }, |
| 111 | OprPropertyFlag::NONE); |
| 112 | }; |
| 113 | |
| 114 | opt.graph().iter(on_opr); |
| 115 | rewriter.apply_inplace(); |
| 116 | #else |
| 117 | MGB_MARK_USED_VAR(opt); |
| 118 | #endif |
| 119 | MIDOUT_E |
| 120 | } |
| 121 | |
| 122 | /* ================= DelayBroadcastPass ================ */ |
| 123 | |