| 267 | } |
| 268 | |
| 269 | void setInputOutputForOps(std::vector<std::shared_ptr<Tensor>>& allTensors, const std::vector<const Op*>& ops, bool isStatic) { |
| 270 | std::set<int> inputIndexes; |
| 271 | std::set<int> outputIndexes; |
| 272 | // 0. deal virtual tensor for static model: |
| 273 | // when : A (Any_Op) -----> B (Raster_Op) |
| 274 | // the tensor will be like below: |
| 275 | // A_outputs : a_tensor |
| 276 | // B_inputs : b_tensor (virtual) |
| 277 | // b_tensor.describe.origin = a_tensor_ptr |
| 278 | // b_tensor is not a InputTensot, a_tensor is not a OutputTensor |
| 279 | // so add b_tensor to OutputIndexes, a_tensor to InputIndexes. |
| 280 | if (isStatic) { |
| 281 | std::unordered_map<Tensor*, int> tensorMap; |
| 282 | for (int index = 0; index < allTensors.size(); index++) { |
| 283 | tensorMap.insert(std::make_pair(allTensors[index].get(), index)); |
| 284 | } |
| 285 | for (int index = 0; index < allTensors.size(); index++) { |
| 286 | auto des = TensorUtils::getDescribe(allTensors[index].get()); |
| 287 | for (int i = 0; i < des->regions.size(); i++) { |
| 288 | outputIndexes.insert(index); |
| 289 | MNN_ASSERT(tensorMap.find(des->regions[i].origin) != tensorMap.end()); |
| 290 | int x = tensorMap[des->regions[i].origin]; |
| 291 | inputIndexes.insert(x); |
| 292 | } |
| 293 | } |
| 294 | } |
| 295 | // 1. insert all output/input index in outputIndexes/inputIndexes |
| 296 | for (auto op : ops) { |
| 297 | if (nullptr != op->outputIndexes()) { |
| 298 | auto data = op->outputIndexes()->data(); |
| 299 | for (int j = 0; j < op->outputIndexes()->size(); ++j) { |
| 300 | outputIndexes.insert(data[j]); |
| 301 | } |
| 302 | } |
| 303 | if (nullptr != op->inputIndexes()) { |
| 304 | auto data = op->inputIndexes()->data(); |
| 305 | for (int j = 0; j < op->inputIndexes()->size(); ++j) { |
| 306 | inputIndexes.insert(data[j]); |
| 307 | } |
| 308 | } |
| 309 | MNN_ASSERT(OpType_Input != op->type()); |
| 310 | } |
| 311 | // 2. the index in outputIndexes/inputIndexed but not in inputIndexes/outputIndexes is output/input |
| 312 | std::set<int> input; |
| 313 | std::set<int> output; |
| 314 | std::set_difference(outputIndexes.begin(), outputIndexes.end(), inputIndexes.begin(), inputIndexes.end(), |
| 315 | std::inserter(output, output.begin())); |
| 316 | std::set_difference(inputIndexes.begin(), inputIndexes.end(), outputIndexes.begin(), outputIndexes.end(), |
| 317 | std::inserter(input, input.begin())); |
| 318 | // 3. set usage for Tensor by index |
| 319 | for (auto index : input) { |
| 320 | auto des = TensorUtils::getDescribe(allTensors[index].get()); |
| 321 | if (des->usage == Tensor::InsideDescribe::CONSTANT || des->usage == Tensor::InsideDescribe::TRAINABLE) { |
| 322 | continue; |
| 323 | } |
| 324 | des->usage = Tensor::InsideDescribe::INPUT; |
| 325 | } |
| 326 | for (auto index : output) { |