| 71 | } // namespace |
| 72 | |
| 73 | void ElemChainImplHelper::on_opr(OperatorNodeBase* opr) { |
| 74 | m_uniq_reader_check.update_on_opr_auto_replace( |
| 75 | opr, m_rewriter.auto_replace_outputs(opr)); |
| 76 | on_opr_visited(opr); |
| 77 | |
| 78 | auto elem = try_cast_as_op<Elemwise>(opr); |
| 79 | Mode mode = elem ? elem->param().mode : Mode::NEGATE; |
| 80 | |
| 81 | bool inp_changed = false; |
| 82 | for (auto i : opr->input()) { |
| 83 | if (m_rewriter.has_manual_replace(i)) { |
| 84 | inp_changed = true; |
| 85 | continue; |
| 86 | } |
| 87 | |
| 88 | auto ielem = try_cast_as_op<Elemwise>(i->owner_opr()); |
| 89 | if (ielem) { |
| 90 | auto imode = ielem->param().mode; |
| 91 | // To ensure that all leaves(chain terms) which found by |
| 92 | // extract_chain_terms have been processed. In other word, |
| 93 | // we would call process_chain in topological order. |
| 94 | if ((!elem || imode != mode || !m_uniq_reader_check(i)) && |
| 95 | check_mode(imode)) { |
| 96 | inp_changed = true; |
| 97 | m_opt_state.call_with_opr( |
| 98 | i->owner_opr(), [&] { this->process_chain(i, imode); }); |
| 99 | } |
| 100 | } |
| 101 | } |
| 102 | if (inp_changed) { |
| 103 | m_uniq_reader_check.update_on_opr_auto_replace( |
| 104 | opr, m_rewriter.auto_replace_outputs(opr)); |
| 105 | } |
| 106 | |
| 107 | if (elem && on_opr_visit_finished(elem)) { |
| 108 | auto ovar = opr->output(0); |
| 109 | if (check_mode(mode) && m_opt_state.graph().endpoint_contain(ovar)) |
| 110 | process_chain(ovar, mode); |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | VarNodeArray ElemChainImplHelper::extract_chain_terms(VarNode* endpoint, Mode mode) { |
| 115 | auto pred = [mode, this, eo = endpoint->owner_opr()](OperatorNodeBase* opr) { |
nothing calls this directly
no test coverage detected