2 * Copyright (c) 2020 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 __LUCI_MICRO_INTERPRETER_MICRO_READER_H__
18 #define __LUCI_MICRO_INTERPRETER_MICRO_READER_H__
20 #include "luci_interpreter/core/ParamsType.h"
21 #include "luci_interpreter/core/DataType.h"
23 #include <circle-generated/circle/schema_generated.h>
29 namespace luci_interpreter
32 #ifdef USE_STATIC_ALLOC
36 using ExecutionPlanTable = std::map<uint32_t, std::vector<uint32_t>>;
38 template <typename VECTORTYPE> uint32_t read_u32(const VECTORTYPE &buffer, uint32_t idx)
40 static_assert(std::is_same<typename VECTORTYPE::value_type, uint8_t>::value, "Types mismatch!");
43 val += (buffer.at(idx + 0) << 0 * 8);
44 val += (buffer.at(idx + 1) << 1 * 8);
45 val += (buffer.at(idx + 2) << 2 * 8);
46 val += (buffer.at(idx + 3) << 3 * 8);
52 namespace read_metadata
55 template <typename VECTORTYPE>
56 ExecutionPlanTable decode_execution_plan(const VECTORTYPE &execution_plan_data)
58 static_assert(std::is_same<typename VECTORTYPE::value_type, uint8_t>::value, "Types mismatch!");
60 ExecutionPlanTable execution_plan_table;
63 if (execution_plan_data.size() < 4)
64 assert(false && "Op table decode error : invalid entry number");
66 uint32_t entry_number = read_u32(execution_plan_data, idx);
67 idx += sizeof(uint32_t);
69 while (idx < execution_plan_data.size())
71 if (idx + 2 * sizeof(uint32_t) > execution_plan_data.size())
72 assert(false && "Op table decode error : invalid entry item");
74 uint32_t id = read_u32(execution_plan_data, idx);
75 idx += sizeof(uint32_t);
77 uint32_t size = read_u32(execution_plan_data, idx);
80 assert(false && "Op table decode error : empty execution plan entry");
82 idx += sizeof(uint32_t);
84 if (idx + sizeof(uint32_t) * size > execution_plan_data.size())
85 assert(false && "Source table decode error : invalid entry data");
87 std::vector<uint32_t> execution_plan_vector;
88 uint32_t position = read_u32(execution_plan_data, idx);
89 idx += sizeof(uint32_t);
91 for (uint32_t j = 1; j < size; ++j)
93 uint32_t execution_plan_inform = read_u32(execution_plan_data, idx);
94 idx += sizeof(uint32_t);
96 execution_plan_vector.push_back(execution_plan_inform);
99 if (!execution_plan_table.insert({position, execution_plan_vector}).second)
100 assert(false && "Op table decode error : duplicated origin ID");
103 if (idx != execution_plan_data.size())
104 assert(false && "Op table decode error : data size invalid");
106 if (execution_plan_table.size() != entry_number)
107 assert(false && "Op table decode error : entry number invalid");
109 return execution_plan_table;
112 } // namespace read_metadata
115 DataType luci_datatype(circle::TensorType type);
116 FusedActFunc luci_actfunc(circle::ActivationFunctionType type);
117 Padding luci_padding(circle::Padding padding);
118 MirrorPadMode luci_mirrorpad_mode(circle::MirrorPadMode mode);
121 * @brief Wrapper to use flatbuffers::Vector pointer as std::vector entity
123 template <typename T> class VectorWrapper
126 explicit VectorWrapper(const flatbuffers::Vector<T> *ptr);
128 const T *data() const;
129 uint32_t size() const;
131 using iterator = typename flatbuffers::Vector<T>::const_iterator;
132 iterator begin() const;
133 iterator end() const;
135 using value_type = typename flatbuffers::Vector<T>::return_type;
136 value_type at(uint32_t i) const;
137 value_type operator[](uint32_t i) const;
143 const flatbuffers::Vector<T> *_vector;
146 template <typename T> VectorWrapper<T> wrap(const flatbuffers::Vector<T> *vec)
148 return VectorWrapper<T>(vec);
152 * @brief Loads Circle file and provides helpers to access attributes
157 using CircleBuffers = VectorWrapper<flatbuffers::Offset<circle::Buffer>>;
158 using CircleTensors = VectorWrapper<flatbuffers::Offset<circle::Tensor>>;
159 using CircleOperators = VectorWrapper<flatbuffers::Offset<circle::Operator>>;
160 using CircleOperatorCodes = VectorWrapper<flatbuffers::Offset<circle::OperatorCode>>;
161 using CircleMetadataSet = VectorWrapper<flatbuffers::Offset<circle::Metadata>>;
164 CircleReader() = default;
166 public: // direct API
167 CircleOperatorCodes opcodes() const { return wrap(_model->operator_codes()); }
168 CircleBuffers buffers() const { return wrap(_model->buffers()); }
169 CircleTensors tensors() const { return wrap(_current_subgraph->tensors()); }
170 CircleOperators operators() const { return wrap(_current_subgraph->operators()); }
171 VectorWrapper<int32_t> inputs() const { return wrap(_current_subgraph->inputs()); }
172 VectorWrapper<int32_t> outputs() const { return wrap(_current_subgraph->outputs()); }
173 circle::DataFormat data_format() const { return _current_subgraph->data_format(); }
174 CircleMetadataSet metadata() const { return wrap(_model->metadata()); }
176 uint32_t num_subgraph() const { return wrap(_model->subgraphs()).size(); }
177 circle::BuiltinOperator builtin_code(const circle::Operator *op) const;
180 bool parse(const circle::Model *model);
181 bool select_subgraph(uint32_t subgraph);
182 uint32_t get_current_subgraph_index() const { return _current_subgraph_index; }
185 const circle::Model *_model{nullptr};
186 const circle::SubGraph *_current_subgraph{nullptr};
187 uint32_t _current_subgraph_index{0};
190 } // namespace luci_interpreter
192 #endif // __LUCI_MICRO_INTERPRETER_MICRO_READER_H__