| 142 | } |
| 143 | |
| 144 | std::vector<Tensor> Module::__trace(const std::vector<Tensor>& inputs, const std::vector<AnyValue>& args) { |
| 145 | auto ir_ctx = Context::instance().thisThread()->ir_context; |
| 146 | |
| 147 | // Generate unique name for this module instance to avoid conflicts with same-name modules |
| 148 | std::string unique_module_name = ir_ctx->getUniqueModuleName(impl_->getAbsoluteName()); |
| 149 | // rename the module impl to unique name |
| 150 | impl_->setAbsoluteName(unique_module_name); |
| 151 | |
| 152 | // Create call graph. |
| 153 | auto call_op = ir_ctx->create<ir::graph::CallGraphOp>(ir_ctx->create<ir::SymbolAttr>(unique_module_name)); |
| 154 | |
| 155 | // Create subgraph under ModuleOp |
| 156 | ir::graph::SubGraphOp::ptr_t this_graph_ir = nullptr; |
| 157 | { |
| 158 | auto guard = ir::IRWriterGuard(ir_ctx, ir_ctx->topLevelOp()->cast_<ir::ModuleOp>()->getTopRegion()); |
| 159 | this_graph_ir = ir_ctx->create<ir::graph::SubGraphOp>(ir_ctx->create<ir::SymbolAttr>(unique_module_name), impl_); |
| 160 | } |
| 161 | this_graph_ir->setDevice(impl_->getDevice()); |
| 162 | |
| 163 | // Wrap the inputs to tensor ir. |
| 164 | std::vector<ir::tensor::TensorValue::ptr_t> inputs_ir = ir::tensor::wrapTensors2TensorIR(ir_ctx.get(), inputs); |
| 165 | |
| 166 | // Link inputs to subgraph. |
| 167 | for (const auto& input_ir : inputs_ir) { |
| 168 | (*input_ir)-- > this_graph_ir; |
| 169 | (*input_ir)-- > call_op; |
| 170 | this_graph_ir->getTopRegion()->inputs().push_back(input_ir); |
| 171 | } |
| 172 | |
| 173 | // Forward |
| 174 | std::vector<Tensor> outputs; |
| 175 | { |
| 176 | ir_ctx->setDevice(impl_->getDevice()); |
| 177 | auto guard = ir::IRWriterGuard(ir_ctx, this_graph_ir->getTopRegion()); |
| 178 | outputs = forward(inputs, args); |
| 179 | } |
| 180 | |
| 181 | // wrap the outputs to tensor ir. |
| 182 | std::vector<std::shared_ptr<ir::tensor::TensorValue>> outputs_ir = ir::tensor::wrapTensors2TensorIR(ir_ctx.get(), outputs); |
| 183 | |
| 184 | // link outputs to subgraph. |
| 185 | for (const auto& output_ir : outputs_ir) { |
| 186 | (*this_graph_ir)-- > output_ir; |
| 187 | (*call_op)-- > output_ir; |
| 188 | this_graph_ir->getTopRegion()->outputs().push_back(output_ir); |
| 189 | } |
| 190 | |
| 191 | // create return op |
| 192 | { |
| 193 | auto guard = ir::IRWriterGuard(ir_ctx, this_graph_ir->getTopRegion()); |
| 194 | std::vector<ir::val_ptr_t> vals; |
| 195 | vals.reserve(outputs_ir.size()); |
| 196 | for (auto& o : outputs_ir) vals.push_back(o); |
| 197 | ir_ctx->create<ir::cf::ReturnOp>(vals); |
| 198 | } |
| 199 | |
| 200 | // return the outputs. |
| 201 | return outputs; |
no test coverage detected