2ad2ad0fb9ca94b0b1027f04ab22c036ef22e744
[platform/core/ml/nnfw.git] / runtime / onert / backend / cpu / 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_TENSOR_H__
18 #define __ONERT_BACKEND_CPU_TENSOR_H__
19
20 #include <backend/cpu_common/Tensor.h>
21 #include <ir/Data.h>
22
23 namespace onert
24 {
25 namespace backend
26 {
27 namespace cpu
28 {
29
30 using Tensor = cpu_common::Tensor;
31
32 /**
33  * @brief Class that uses data from external memory that is not managed by a backend
34  *        instead of allocating and copying the data. ExternalTensor's data pointer points to
35  *        an address of memory such as where memory is already allocated, or mmapped area.
36  *        This is meaning that ExternalTensor can take all of types' ir::Data.
37  *        To support this, assume below things no padding, always NHWC layout,
38  *        constant tensor and not dynamic.
39  */
40 class ExternalTensor : public Tensor
41 {
42 public:
43   ExternalTensor() = delete;
44   virtual ~ExternalTensor();
45
46 public:
47   ExternalTensor(const ir::OperandInfo &info, const ir::Layout layout)
48       : Tensor(info, layout, nullptr)
49   {
50     assert(_layout == ir::Layout::NHWC);
51     assert(_info.isConstant());
52     assert(_info.isDynamic() == false);
53   }
54
55 public:
56   /**
57    * @brief     set Data to be shared from external so that this ExternalTensor will not be
58    *            allocated on CPU backend
59    * @param[in] data    data of Operand to be set
60    */
61   void setData(const std::shared_ptr<ir::Data> data)
62   {
63     assert(data != nullptr);
64     _data = data;
65     // Note. Some op such as cker::Conv could take buffer as nullptr.
66     // That's why _buffer also would be used
67     _buffer = const_cast<uint8_t *>(_data->base());
68   }
69
70 public:
71   uint8_t *buffer() const override { return _buffer; }
72
73   bool is_constant() const override { return true; }
74   bool is_dynamic() const override { return false; }
75   void set_dynamic() override
76   {
77     throw std::runtime_error("This tensor does not support changing dynamic");
78   }
79
80   void setShape(const ir::Shape &) override
81   {
82     throw std::runtime_error("This tensor does not support changing shape");
83   }
84
85   void increase_ref() override { ++_num_references; }
86
87   void decrease_ref() override
88   {
89     assert(_data != nullptr);
90     assert(_num_references > 0);
91     --_num_references;
92     if (_num_references == 0)
93     {
94       _data.reset();
95       _buffer = nullptr;
96     }
97   }
98
99   /**
100    * @brief Reset reference count to zero and release data
101    */
102   void reset_ref() override
103   {
104     assert(_data != nullptr);
105     assert(_num_references > 0);
106     _num_references = 0;
107
108     _data.reset();
109     _buffer = nullptr;
110   }
111
112   int32_t num_references() override { return _num_references; }
113
114 private:
115   std::shared_ptr<const ir::Data> _data;
116 };
117
118 } // namespace cpu
119 } // namespace backend
120 } // namespace onert
121
122 #endif // __ONERT_BACKEND_CPU_TENSOR_H__