| 312 | } |
| 313 | |
| 314 | static void _setInputOutputForOps(std::vector<std::shared_ptr<Tensor>>& allTensors, const std::vector<const Op*>& ops) { |
| 315 | std::set<int> inputIndexes; |
| 316 | std::set<int> outputIndexes; |
| 317 | // 0. deal virtual tensor for static model: |
| 318 | // when : A (Any_Op) -----> B (Raster_Op) |
| 319 | // the tensor will be like below: |
| 320 | // A_outputs : a_tensor |
| 321 | // B_inputs : b_tensor (virtual) |
| 322 | // b_tensor.describe.origin = a_tensor_ptr |
| 323 | // b_tensor is not a InputTensot, a_tensor is not a OutputTensor |
| 324 | // so add b_tensor to OutputIndexes, a_tensor to InputIndexes. |
| 325 | // 1. insert all output/input index in outputIndexes/inputIndexes |
| 326 | for (auto op : ops) { |
| 327 | if (nullptr != op->outputIndexes()) { |
| 328 | auto data = op->outputIndexes()->data(); |
| 329 | for (int j = 0; j < op->outputIndexes()->size(); ++j) { |
| 330 | outputIndexes.insert(data[j]); |
| 331 | } |
| 332 | } |
| 333 | if (nullptr != op->inputIndexes()) { |
| 334 | auto data = op->inputIndexes()->data(); |
| 335 | for (int j = 0; j < op->inputIndexes()->size(); ++j) { |
| 336 | inputIndexes.insert(data[j]); |
| 337 | } |
| 338 | } |
| 339 | MNN_ASSERT(OpType_Input != op->type()); |
| 340 | } |
| 341 | // 2. the index in outputIndexes/inputIndexed but not in inputIndexes/outputIndexes is output/input |
| 342 | std::set<int> input; |
| 343 | std::set<int> output; |
| 344 | std::set_difference(outputIndexes.begin(), outputIndexes.end(), inputIndexes.begin(), inputIndexes.end(), |
| 345 | std::inserter(output, output.begin())); |
| 346 | std::set_difference(inputIndexes.begin(), inputIndexes.end(), outputIndexes.begin(), outputIndexes.end(), |
| 347 | std::inserter(input, input.begin())); |
| 348 | // 3. set usage for Tensor by index |
| 349 | for (auto index : input) { |
| 350 | auto des = TensorUtils::getDescribe(allTensors[index].get()); |
| 351 | if (des->usage == Tensor::InsideDescribe::CONSTANT || des->usage == Tensor::InsideDescribe::TRAINABLE) { |
| 352 | continue; |
| 353 | } |
| 354 | des->usage = Tensor::InsideDescribe::INPUT; |
| 355 | } |
| 356 | for (auto index : output) { |
| 357 | auto des = TensorUtils::getDescribe(allTensors[index].get()); |
| 358 | if (des->usage == Tensor::InsideDescribe::NORMAL) { |
| 359 | des->usage = TensorUsage::OUTPUT; |
| 360 | } |
| 361 | } |
| 362 | } |
| 363 | |
| 364 | void _getConstData(const Net* net, std::vector<MNN::Express::VARP> inputs, const std::set<int>& inputIndexes, |
| 365 | const std::set<int>& outputIndexes, |