Imported Upstream version 1.4.0
[platform/core/ml/nnfw.git] / runtime / onert / backend / cpu / operand / Tensor.h
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #ifndef __ONERT_BACKEND_CPU_OPERAND_TENSOR_H__
18 #define __ONERT_BACKEND_CPU_OPERAND_TENSOR_H__
19
20 #include "Allocator.h"
21
22 #include <backend/ITensor.h>
23 #include <ir/OperandInfo.h>
24
25 namespace onert
26 {
27 namespace backend
28 {
29 namespace cpu
30 {
31 namespace operand
32 {
33
34 class Tensor : public ITensor
35 {
36 public:
37   Tensor() = delete;
38
39 public:
40   Tensor(const ir::OperandInfo &info)
41       : _info(info), _buffer(nullptr), _num_references(0), _allocator(nullptr)
42   {
43     // DO NOTHING
44   }
45
46 public:
47   // Only one of two method 'setBuffer' must be called once
48   void setBuffer(uint8_t *buffer)
49   {
50     assert(_buffer == nullptr && _allocator == nullptr);
51     _buffer = buffer;
52   }
53   void setBuffer(const std::shared_ptr<cpu_common::Allocator> &alloc)
54   {
55     assert(_buffer == nullptr && _allocator == nullptr);
56     _allocator = alloc;
57   }
58   ir::DataType data_type() const { return _info.typeInfo().type(); }
59   float scale() const { return _info.typeInfo().scale(); }
60   int32_t offset() const { return _info.typeInfo().offset(); }
61
62 public:
63   uint8_t *buffer() const override
64   {
65     if (_allocator != nullptr)
66       return _allocator->base();
67     else
68       return _buffer;
69   }
70   /**
71    * @brief Get dimension by index
72    *
73    * @param index Index to get diemension
74    * @return size_t Dimension at index
75    * @note N : dimension(0)
76    *       H : dimension(1)
77    *       W : dimension(2)
78    *       C : dimension(3)
79    */
80   size_t dimension(size_t index) const override { return _info.shape().dim(index); }
81   size_t num_dimensions() const override { return _info.shape().rank(); }
82   size_t total_size() const override { return _info.total_size(); }
83   size_t calcOffset(const ir::Coordinates &coords) const override;
84   ir::Layout layout() const override { return ir::Layout::NHWC; }
85   bool has_padding() const override { return false; }
86   void access(const std::function<void(ITensor &tensor)> &fn) final;
87   bool is_dynamic() const override { return _info.memAllocType() == ir::MemAllocType::DYNAMIC; }
88
89   void increase_ref()
90   {
91     assert(_buffer != nullptr || _allocator != nullptr);
92     ++_num_references;
93   }
94   void decrease_ref()
95   {
96     assert(_buffer != nullptr || _allocator != nullptr);
97     assert(_num_references > 0);
98     --_num_references;
99     // Only constant tensor has allocator pointer
100     if (_num_references == 0)
101     {
102       if (_buffer != nullptr)
103         _buffer = nullptr;
104       else
105       {
106         _allocator->release();
107         _allocator = nullptr;
108       }
109     }
110   }
111
112 private:
113   ir::OperandInfo _info;
114   uint8_t *_buffer;
115   int32_t _num_references;
116   std::shared_ptr<cpu_common::Allocator> _allocator;
117 };
118
119 } // namespace operand
120 } // namespace cpu
121 } // namespace backend
122 } // namespace onert
123
124 #endif // __ONERT_BACKEND_CPU_OPERAND_TENSOR_H__