2 * Copyright (c) 2018 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 #ifndef __ONERT_BACKEND_CPU_COMMON_TENSOR_H__
18 #define __ONERT_BACKEND_CPU_COMMON_TENSOR_H__
20 #include "Allocator.h"
22 #include <backend/IPortableTensor.h>
23 #include <ir/OperandInfo.h>
32 class DynamicMemoryManager;
34 class Tensor : public IPortableTensor
41 Tensor(const ir::OperandInfo &info, const ir::Layout layout,
42 DynamicMemoryManager *dynamic_mem_mgr)
43 : IPortableTensor(info), _layout(layout), _buffer(nullptr), _num_references(0),
44 _dynamic_mem_mgr(dynamic_mem_mgr), _allocator(nullptr)
50 // Only one of two method 'setBuffer' must be called once
53 * @brief Set the Buffer object. This method is called for static and non-const tensor
55 void setBuffer(uint8_t *buffer)
57 assert(_buffer == nullptr);
62 * @brief Set the Buffer object. This method is called for dynamic or const tensor
64 void setBuffer(const std::shared_ptr<Allocator> &alloc)
66 assert(_buffer == nullptr);
68 _buffer = alloc->base();
71 // This works just as setBuffer but it simply overwrite existing Allocator without nullptr check
72 void overwriteBuffer(const std::shared_ptr<Allocator> &alloc)
75 _buffer = alloc->base();
79 * @brief Mark this tensor does not have memory.
80 * Real memory deallocation should be done by caller.
89 uint8_t *buffer() const override { return _buffer; }
91 * @brief Get dimension by index
93 * @param index Index to get diemension
94 * @return size_t Dimension at index
95 * @note N : dimension(0)
100 size_t dimension(size_t index) const final override { return _info.shape().dim(index); }
101 size_t num_dimensions() const override { return _info.shape().rank(); }
102 size_t total_size() const override { return _info.total_size(); }
103 size_t calcOffset(const ir::Coordinates &coords) const override;
104 ir::Layout layout() const override { return _layout; }
105 ir::DataType data_type() const override { return _info.typeInfo().type(); }
106 float data_scale() const override { return _info.typeInfo().scale(); }
107 int32_t data_offset() const override { return _info.typeInfo().offset(); }
108 bool is_constant() const override { return _info.isConstant(); }
109 bool is_dynamic() const override { return _info.isDynamic(); }
110 void set_dynamic() override { _info.setDynamic(); }
111 bool applyShape(const ir::Shape &new_shape) override;
112 const ir::Sparsity *sparsity() const override { return _info.typeInfo().sparsity(); }
114 virtual void increase_ref()
116 assert(is_dynamic() ||
118 (_buffer != nullptr));
123 virtual void decrease_ref()
125 assert(_buffer != nullptr || _allocator != nullptr);
126 assert(_num_references > 0);
128 // constant tensor and dynamic tensor has _allocator
129 if (_num_references == 0)
131 if (_buffer != nullptr)
133 if (_allocator != nullptr)
135 _allocator->release();
136 _allocator = nullptr;
142 * @brief Reset reference count to zero and release data
144 virtual void reset_ref()
146 assert(_buffer != nullptr || _allocator != nullptr);
147 assert(_num_references > 0);
150 // Only constant tensor has allocator pointer
151 if (_buffer != nullptr)
155 _allocator->release();
156 _allocator = nullptr;
160 virtual int32_t num_references() { return _num_references; }
162 void setShape(const ir::Shape &new_shape) override;
167 int32_t _num_references;
168 DynamicMemoryManager *_dynamic_mem_mgr;
172 * @brief Memory allocator for dynamic tensor and const tensor
173 * Since maintaing _allocator and also _buffer makes confusion,
174 * we will mainly use _buffer (not _allocator.base()) for memory pointer in this code.
175 * _allocator(shared_ptr) is used to guarantee that we have valid _buffer.
177 std::shared_ptr<Allocator> _allocator;
180 } // namespace cpu_common
181 } // namespace backend
184 #endif // __ONERT_BACKEND_CPU_COMMON_TENSOR_H__