| 454 | } |
| 455 | |
| 456 | static void |
| 457 | _findAllConstTensorIndex(const Net* net, const std::set<int>& inputIndexes, const std::set<int>& outputIndexes, |
| 458 | std::shared_ptr<Schedule::ScheduleInfo> sharedConst, std::vector<int>& constOpId, |
| 459 | std::map<int, std::tuple<int, int, std::vector<int>, std::vector<char>>>* constTensorData) { |
| 460 | auto selectOps = _collectNeededOps(net, inputIndexes, outputIndexes); |
| 461 | std::set<int> constTensorIndex; |
| 462 | // 0: not used, 1: const, 2: output |
| 463 | std::vector<uint8_t> constMask(sharedConst->allTensors.size(), 0); |
| 464 | for (int i = 0; i < sharedConst->allTensors.size(); ++i) { |
| 465 | if (sharedConst->allTensors[i].get() != nullptr) { |
| 466 | constMask[i] = 1; |
| 467 | } |
| 468 | } |
| 469 | for (int v = 0; v < selectOps.size(); ++v) { |
| 470 | auto op = net->oplists()->GetAs<Op>(selectOps[v]); |
| 471 | if (nullptr == op->outputIndexes()) { |
| 472 | continue; |
| 473 | } |
| 474 | bool isConst = true; |
| 475 | if (nullptr != op->inputIndexes()) { |
| 476 | for (int i = 0; i < op->inputIndexes()->size(); ++i) { |
| 477 | auto index = op->inputIndexes()->data()[i]; |
| 478 | if (constMask[index]) { |
| 479 | continue; |
| 480 | } |
| 481 | if (OpCommonUtils::opNeedContent(op, i)) { |
| 482 | isConst = false; |
| 483 | break; |
| 484 | } |
| 485 | } |
| 486 | } |
| 487 | if (isConst) { |
| 488 | for (int i = 0; i < op->outputIndexes()->size(); ++i) { |
| 489 | auto index = op->outputIndexes()->data()[i]; |
| 490 | constMask[index] = 1; |
| 491 | constTensorData->emplace(index, std::make_tuple(0, 0, std::vector<int>(0), std::vector<char>(0))); |
| 492 | constOpId.push_back(selectOps[v]); |
| 493 | } |
| 494 | } |
| 495 | } |
| 496 | } |
| 497 | |
| 498 | static NetT* _replaceConstOp(const void* buffer, size_t bufferSize, |
| 499 | std::map<int, std::tuple<int, int, std::vector<int>, std::vector<char>>>& constTensorData, |