2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "backend/cpu_common/DynamicTensorManager.h"
19 #include "util/logging.h"
28 DynamicTensorManager::DynamicTensorManager(const std::shared_ptr<TensorRegistry> ®)
29 : _dynamic_mem_mgr{new DynamicMemoryManager()}, _tensors{reg}
34 void DynamicTensorManager::applyShape(const ir::OperandIndex &ind, const ir::Shape &new_shape)
36 VERBOSE_F() << ind << std::endl;
38 auto tensor = _tensors->getNativeTensor(ind);
41 bool previously_dynamic = tensor->is_dynamic();
43 auto allocTensorMem = [&](bool overwrite = false) {
44 auto capacity = tensor->total_size();
45 auto alloc = _dynamic_mem_mgr->allocate(ind, capacity);
48 tensor->overwriteBuffer(alloc);
50 tensor->setBuffer(alloc);
53 if (!previously_dynamic)
55 // TODO deallocate tensor->buffer()
56 // issue is that staticTensorManager might have allocate this memory
57 tensor->setShape(new_shape);
58 tensor->set_dynamic();
61 else if (tensor->buffer() == nullptr)
63 tensor->setShape(new_shape);
64 tensor->set_dynamic();
67 // when buffer was already allocated and new_shape requires different size
70 auto previous_size = tensor->total_size();
71 auto new_size = new_shape.num_elements() * sizeOfDataType(tensor->data_type());
72 if (previous_size != new_size)
74 _dynamic_mem_mgr->deallocate(ind);
76 tensor->setShape(new_shape);
77 tensor->set_dynamic();
81 { // when buffer with same size was already allocated, shape could differ
82 tensor->setShape(new_shape);
87 void DynamicTensorManager::buildTensor(const ir::OperandIndex &ind,
88 const ir::OperandInfo &tensor_info,
89 ir::Layout backend_layout)
91 assert(_tensors->getNativeTensor(ind) == nullptr);
92 auto tensor = std::make_shared<Tensor>(tensor_info, backend_layout, this);
93 _tensors->setNativeTensor(ind, tensor);
96 void DynamicTensorManager::planDealloc(ir::OperationIndex op_ind, ir::OperandIndex operand_ind)
98 _dealloc_tensor_map[op_ind].emplace(operand_ind);
101 void DynamicTensorManager::deallocInput(ir::OperationIndex op_ind)
103 auto find = _dealloc_tensor_map.find(op_ind);
104 if (find == _dealloc_tensor_map.end())
107 auto &input_set = find->second;
108 for (auto input_ind : input_set)
110 auto *tensor = _tensors->getNativeTensor(input_ind).get();
111 if (!tensor->is_dynamic())
114 _dynamic_mem_mgr->deallocate(input_ind);
115 tensor->resetBuffer();
117 VERBOSE(DynamicTensorManager) << "Deallocating #" << input_ind.value()
118 << " (input of op_ind: " << op_ind.value() << ")" << std::endl;
122 void DynamicTensorManager::deallocSubgraphOutput(ir::OperandIndex output_ind)
124 auto *tensor = _tensors->getNativeTensor(output_ind).get();
125 if (!tensor->is_dynamic())
128 _dynamic_mem_mgr->deallocate(output_ind);
129 tensor->resetBuffer();
131 VERBOSE(DynamicTensorManager) << "Deallocating #" << output_ind.value()
132 << " (output of a subgraph)" << std::endl;
135 } // namespace cpu_common
136 } // namespace backend