| 83 | } |
| 84 | |
| 85 | std::unique_ptr<cg::AsyncExecutable> LoopImpl::DescImplBase::compile() { |
| 86 | // build output spec |
| 87 | ComputingGraph::OutputSpec out_spec; |
| 88 | |
| 89 | out_spec.push_back(m_loop_cond_manager.subgraph_outspec_item()); |
| 90 | if (auto s = m_owner_loop_opr->m_mutable_state_saver.get()) { |
| 91 | s->update_subgraph_outspec(out_spec); |
| 92 | } |
| 93 | |
| 94 | for (auto&& i : m_output_record_spec) { |
| 95 | if (!i.enabled()) |
| 96 | continue; |
| 97 | |
| 98 | auto cb = [ptr = &i](const DeviceTensorND& dev) { |
| 99 | ptr->recorder()->on_val_produced(dev); |
| 100 | }; |
| 101 | out_spec.push_back({i.var_sub(), cb}); |
| 102 | } |
| 103 | |
| 104 | on_sub_graph_func_compile(out_spec); |
| 105 | auto func = m_sub_graph->compile(out_spec); |
| 106 | |
| 107 | // find used input, and check unique comp node |
| 108 | if (!m_cur_func_input.valid()) |
| 109 | m_cur_func_input = std::vector<InputMaker*>(); |
| 110 | auto&& inp = m_cur_func_input.val(); |
| 111 | inp.clear(); |
| 112 | CompNode the_comp_node; |
| 113 | ThinHashSet<OperatorNodeBase*> visited; |
| 114 | auto cb = [&inp, &the_comp_node, &visited](OperatorNodeBase* opr) { |
| 115 | visited.insert(opr); |
| 116 | if (opr->same_type<InputMaker>()) { |
| 117 | inp.push_back(&opr->cast_final<InputMaker>()); |
| 118 | } |
| 119 | for (auto i : opr->output()) { |
| 120 | if (!the_comp_node.valid()) |
| 121 | the_comp_node = i->comp_node(); |
| 122 | else { |
| 123 | mgb_assert( |
| 124 | the_comp_node == i->comp_node(), |
| 125 | "different comp nodes encountered in subgraph of loop: " |
| 126 | "expect=%s get=%s (from %s)", |
| 127 | the_comp_node.to_string().c_str(), |
| 128 | i->comp_node().to_string().c_str(), |
| 129 | cg::dump_var_info({i}).c_str()); |
| 130 | } |
| 131 | } |
| 132 | return true; |
| 133 | }; |
| 134 | func->iter_opr_seq(cb); |
| 135 | for (auto&& i : func->get_rt_static_source_deps()) { |
| 136 | auto opr = i.dest->owner_opr(); |
| 137 | if (visited.insert(opr).second && opr->same_type<InputMaker>()) { |
| 138 | inp.push_back(&opr->cast_final<InputMaker>()); |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | return func; |