Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / compiler / nnc / backends / soft_backend / code_snippets / cpp_header_types.def
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 #include <cstring>
18 #include <initializer_list>
19 #include <memory>
20 #include <cassert>
21 #include <algorithm>
22
23 using index_t = long;
24
25 const index_t MAX_DIMS = 8;
26
27 /** @brief Shape of Tensor object
28  *
29  * This class represents size of multidimensional table
30  */
31 class Shape
32 {
33 public:
34
35   Shape()
36   {
37     _dims = 0;
38   }
39
40   template <class T>
41   Shape(std::initializer_list<T> data): _dims(data.size())
42   {
43     assert(_dims <= MAX_DIMS);
44     index_t *dataPtr = _data;
45     for (T value: data)
46     {
47       *dataPtr++ = static_cast<index_t>(value);
48     }
49   }
50
51   Shape(const Shape &orig): _dims(orig._dims)
52   {
53     for (index_t i = 0; i < _dims; ++i)
54       _data[i] = orig._data[i];
55   }
56
57   Shape &operator=(const Shape &orig)
58   {
59     _dims = orig._dims;
60     for (index_t i = 0; i < _dims; ++i)
61       _data[i] = orig._data[i];
62     return *this;
63   }
64
65   /** Returns number of table dimensions*/
66   index_t getDims() const
67   {
68     return _dims;
69   }
70
71   /** Sets number of table dimensions*/
72   void setDims(index_t dims)
73   {
74     assert(dims < MAX_DIMS);
75     _dims = dims;
76   }
77
78   /** Returns size of selected dimension*/
79   index_t &operator[](index_t dim)
80   {
81     assert(dim < _dims);
82     return _data[dim];
83   }
84
85   /** Returns size of selected dimension, constant version*/
86   index_t operator[](index_t dim) const
87   {
88     assert(dim < _dims);
89     return _data[dim];
90   }
91
92   /** Returns number of elements in table*/
93   index_t getNumElems() const
94   {
95     index_t volume = 1;
96     for (index_t i = 0; i < _dims; ++i)
97     {
98       volume *= _data[i];
99     }
100     return volume;
101   }
102
103 private:
104   index_t _data[MAX_DIMS];
105   index_t _dims;
106 };
107
108 /** This class points to one cell in table*/
109 using Index = Shape;
110
111 /** @brief Multidimensional table
112  *
113  * This class represents multidimensional table.
114  * It is used to provide NN model interface and intermediate objects in inference sequence.
115  */
116 class Tensor
117 {
118 public:
119   Tensor(): Tensor(Shape{}){}
120
121   Tensor(Tensor &&orig): _shape(orig._shape), _data(orig._data), _managed(orig._managed)
122   {
123     orig._managed = false;
124   }
125
126   /** Constructs table, that references external data as its content*/
127   Tensor(const Shape& shape, float *data): _shape(shape), _data(data){}
128
129   Tensor(const Shape& shape): _shape(shape), _data(new float[shape.getNumElems()]), _managed(true) {}
130
131   ~Tensor()
132   {
133     if (_managed)
134       delete [] _data;
135   }
136
137   /** Copies data from external source into table*/
138   void fillData(const float *data, const index_t num_elements)
139   {
140     assert(_managed);
141     std::memcpy(_data, data, num_elements * sizeof(float));
142   }
143
144   Tensor& operator=(const Tensor& t) {
145     if (this == &t)
146       return *this;
147
148     if (!t._managed) {
149       if (_managed)
150         delete [] _data;
151
152       _managed = false;
153       _data = t._data;
154       _shape = t._shape;
155     } else {
156       // this tensor is not constant so we can write data into it
157       assert(_managed);
158       reshape(t._shape);
159       fillData(t._data, _shape.getNumElems());
160     }
161
162     return *this;
163   }
164
165   /** Access element in table by index*/
166   float &at(const Index &idx)
167   {
168     return *(_data + getOffset(idx));
169   }
170
171   /** Access element in table by index, constant version*/
172   float at(const Index &idx) const
173   {
174     return *(_data + getOffset(idx));
175   }
176
177   void reshape(const Shape &shape)
178   {
179     index_t oldVolume = _shape.getNumElems();
180     _shape = shape;
181     if (_managed && oldVolume != shape.getNumElems())
182     {
183       float* new_data = new float[shape.getNumElems()];
184       delete [] _data;
185       std::swap(new_data, _data);
186     }
187   }
188
189   /** Free memory, set empty shape */
190   void clean()
191   {
192     _shape.setDims(0);
193     if (_managed)
194       delete [] _data;
195     _managed = false;
196   }
197
198   /** Returns pointer to raw data*/
199   float *getData()
200   {
201     return _data;
202   }
203
204   /** Returns pointer to raw data, constant version*/
205   const float *getData() const
206   {
207     return _data;
208   }
209
210   /** Returns size object of this table*/
211   const Shape &getShape() const
212   {
213     return _shape;
214   }
215
216 private:
217   index_t getOffset(const Index &idx) const
218   {
219     assert(idx.getDims() == _shape.getDims());
220     index_t offset = 0;
221     index_t stride = 1;
222     for (index_t i = _shape.getDims() - 1; i >= 0; --i)
223     {
224       assert(idx[i] < _shape[i]);
225       offset += stride * idx[i];
226       stride *= _shape[i];
227     }
228     return offset;
229   }
230
231   Shape _shape;
232   float *_data;
233   bool _managed = false;
234 };