ONE - On-device Neural Engine
Loading...
Searching...
No Matches
luci::CircleConstNodeBuilder Class Reference

Builder creates CircleConst node from Tensor with buffer. More...

#include <CircleConst.h>

Collaboration diagram for luci::CircleConstNodeBuilder:

Public Member Functions

CircleNodebuild (TensorIndex tensor_index, GraphBuilderContext *ctx) const final
 
- Public Member Functions inherited from luci::TypedNodeBuilder< NodeBuilderType::BUFFER >
NodeBuilderType builder_type () const final
 
- Public Member Functions inherited from luci::NodeBuilderBase
virtual ~NodeBuilderBase ()=default
 

Detailed Description

Builder creates CircleConst node from Tensor with buffer.

Definition at line 30 of file CircleConst.h.

Member Function Documentation

◆ build()

CircleNode * luci::CircleConstNodeBuilder::build ( TensorIndex  tensor_index,
GraphBuilderContext ctx 
) const
finalvirtual

Implements luci::NodeBuilderBase.

Definition at line 147 of file CircleConst.cpp.

149{
150 assert(tensor_index >= 0);
151 LOGGER(l);
152
153 auto graph = context->graph();
154 auto reader = context->reader();
155 const auto tensors = reader->tensors();
156 const auto const_tensor = tensors[tensor_index];
157 assert(const_tensor != nullptr);
158 if (const_tensor->is_variable())
159 {
160 // Create CircleVariable for variable
161 return nullptr;
162 }
163
164 const auto r_buffers = reader->buffers();
165 const auto c_buffer = const_tensor->buffer();
166 const auto r_buffer = r_buffers[c_buffer];
167 assert(r_buffer != nullptr);
168 if (r_buffer->offset() == 1 || r_buffer->size() == 1)
169 {
170 // NOTE this shouldn't happen
171 throw std::runtime_error("CircleConst: Circle file with invalid extended Buffer.");
172 }
173 // temporary buffer to provide raw data from file
174 // must have life time same or longer than 'buffer' variable
175 std::vector<uint8_t> temp_buffer;
176 luci::VectorWrapper<uint8_t> buffer(nullptr);
177 if (r_buffer->offset() > 1)
178 {
179 if (r_buffer->size() >= std::numeric_limits<uint32_t>::max())
180 {
181 // NOTE uint32_t limit is to match "uoffset_t flatbuffers::Vector::size()"
182 throw std::runtime_error("CircleConst: Circle file with invalid extended Buffer.");
183 }
184 uint32_t r_size = static_cast<uint32_t>(r_buffer->size());
185 // match binary level to flatbuffers::Vector
186 temp_buffer.resize(r_size + sizeof(uint32_t));
187
188 uint8_t *t_data = temp_buffer.data();
189 const uint8_t *f_data = reader->file_data(r_buffer->offset());
190 if (f_data == nullptr)
191 {
192 // NOTE this shouldn't happen
193 assert(false);
194 return nullptr;
195 }
196 memcpy(t_data, &r_size, sizeof(r_size));
197 t_data = t_data + sizeof(r_size);
198 if (r_buffer->offset() + r_buffer->size() > reader->file_size())
199 {
200 // NOTE this shouldn't happen
201 assert(false);
202 return nullptr;
203 }
204 memcpy(t_data, f_data, r_buffer->size());
205
206 using fbv_t = flatbuffers::Vector<uint8_t>;
207 const fbv_t *v_data = reinterpret_cast<const fbv_t *>(temp_buffer.data());
208 buffer = wrap(v_data);
209
210 context->ext_buffer(true);
211 }
212 else
213 {
214 buffer = wrap(r_buffer->data());
215 }
216 const auto const_dims = wrap(const_tensor->shape()); // in NHWC
217 if (const_dims.size() == 0 && buffer.empty())
218 {
219 // unknown shape tensor and scalar tensor
220 return nullptr;
221 }
222
223 // if tensor_index is used as output to some other operator, this is not a constant
224 auto tensoroutputs = context->tensoroutputs();
225 if (tensoroutputs->find(tensor_index))
226 {
227 // other operator output tensor
228 return nullptr;
229 }
230
231 uint32_t num_elements = 1;
232 for (uint32_t r = 0; r < const_dims.size(); ++r)
233 {
234 num_elements = num_elements * const_dims[r];
235 }
236
237 if (buffer.empty() && num_elements > 0)
238 {
239 // normal empty tensor
240 return nullptr;
241 }
242
243 auto const_node = graph->nodes()->create<CircleConst>();
244 copy_tensor_attributes(const_tensor, const_node);
245 const_node->shape_status(luci::ShapeStatus::VALID);
246 INFO(l) << "[luci] NodeFinder const_node(" << tensor_index << ") -> " << const_node << " "
247 << const_dims << std::endl;
248 if (num_elements > 0)
249 {
250 switch (luci_datatype(const_tensor->type()))
251 {
252 case loco::DataType::FLOAT32:
253 copy_data<loco::DataType::FLOAT32>(buffer, num_elements, const_node);
254 break;
255
256 case loco::DataType::FLOAT16:
257 copy_data<loco::DataType::FLOAT16>(buffer, num_elements, const_node);
258 break;
259
260 case loco::DataType::U4:
261 copy_data_4<loco::DataType::U4>(buffer, num_elements, const_node);
262 break;
263
264 case loco::DataType::U8:
265 copy_data<loco::DataType::U8>(buffer, num_elements, const_node);
266 break;
267
268 case loco::DataType::S4:
269 copy_data_4<loco::DataType::S4>(buffer, num_elements, const_node);
270 break;
271
272 case loco::DataType::S8:
273 copy_data<loco::DataType::S8>(buffer, num_elements, const_node);
274 break;
275
276 case loco::DataType::S16:
277 copy_data<loco::DataType::S16>(buffer, num_elements, const_node);
278 break;
279
280 case loco::DataType::S32:
281 copy_data<loco::DataType::S32>(buffer, num_elements, const_node);
282 break;
283
284 case loco::DataType::S64:
285 copy_data<loco::DataType::S64>(buffer, num_elements, const_node);
286 break;
287
288 case loco::DataType::BOOL:
289 copy_data<loco::DataType::BOOL>(buffer, num_elements, const_node);
290 break;
291
292 case loco::DataType::STRING:
293 copy_data<loco::DataType::STRING>(buffer, num_elements, const_node);
294 break;
295
296 default:
297 throw oops::UserExn("Unsupported tensor type",
298 circle::EnumNameTensorType(const_tensor->type()));
299 }
300 }
301
302 return const_node;
303}
#define LOGGER(name)
Definition Log.h:65
#define INFO(name)
Definition Log.h:68
Class to build tensor data.
Definition CircleConst.h:35
Wrapper to use flatbuffers::Vector pointer as std::vector entity.
Exception to user.
Definition UserExn.h:42
loco::DataType luci_datatype(circle::TensorType type)
void copy_tensor_attributes(const circle::Tensor *tensor, CircleNode *node)
Copy common tensor attributes such as name, type, etc. to node.
VectorWrapper< T > wrap(const flatbuffers::Vector< T > *vec)
uint32_t num_elements(const Shape &shape)
The number of elements of a feature map of a given shape.
Definition Shape.h:59

References luci::copy_tensor_attributes(), luci::VectorWrapper< T >::empty(), luci::GraphBuilderContext::ext_buffer(), luci::GraphBuilderContext::graph(), INFO, LOGGER, luci::luci_datatype(), luci::GraphBuilderContext::reader(), luci::CircleNode::shape_status(), luci::GraphBuilderContext::tensoroutputs(), luci::CircleReader::tensors(), luci::VALID, and luci::wrap().


The documentation for this class was generated from the following files: