| 756 | } |
| 757 | |
| 758 | static void CalculateMemBlocks(std::vector<int>& mem_block, Subgraph* sub_graph) |
| 759 | { |
| 760 | // first calculate max var tensor exists |
| 761 | tensor_map_t tensor_map; |
| 762 | |
| 763 | const std::vector<Node*>& seq_nodes = sub_graph->seq_nodes; |
| 764 | |
| 765 | int node_number = seq_nodes.size(); |
| 766 | int max_active_num = 0; |
| 767 | int active_num = 0; |
| 768 | |
| 769 | for(int i = 0; i < node_number; i++) |
| 770 | { |
| 771 | Node* node = seq_nodes[i]; |
| 772 | |
| 773 | // first, add output tensor into map |
| 774 | if(!node->IsDynamicShape() && node->ExistAttr(ATTR_NODE_OPS)) |
| 775 | { |
| 776 | for(unsigned int j = 0; j < node->GetOutputNum(); j++) |
| 777 | { |
| 778 | Tensor* tensor = node->GetOutputTensor(j); |
| 779 | |
| 780 | if(get_tensor_mem(tensor)) |
| 781 | continue; |
| 782 | |
| 783 | int consumer_number = tensor->consumer.size(); |
| 784 | |
| 785 | tensor_map[tensor] = consumer_number; |
| 786 | active_num++; |
| 787 | } |
| 788 | } |
| 789 | |
| 790 | if(active_num > max_active_num) |
| 791 | max_active_num = active_num; |
| 792 | |
| 793 | // second, reduce the active_num by release input |
| 794 | for(unsigned int j = 0; j < node->GetInputNum(); j++) |
| 795 | { |
| 796 | Tensor* tensor = node->GetInputTensor(j); |
| 797 | |
| 798 | if(tensor_map.count(tensor) == 0) |
| 799 | continue; |
| 800 | |
| 801 | auto ir = tensor_map.find(tensor); |
| 802 | |
| 803 | ir->second--; |
| 804 | |
| 805 | if(ir->second == 0) |
| 806 | { |
| 807 | active_num--; |
| 808 | tensor_map.erase(ir); |
| 809 | } |
| 810 | } |
| 811 | } |
| 812 | |
| 813 | // suppose each output node only has one output tensor |
| 814 | if(active_num > ( int )sub_graph->output_nodes.size()) |
| 815 | { |
no test coverage detected