{
bool is_valid(const circle::OperatorCodeT &opcode);
+bool is_valid(const circle::OperatorCode *opcode);
+
bool is_custom(const circle::OperatorCodeT &opcode);
+bool is_custom(const circle::OperatorCode *opcode);
+
std::string opcode_name(const circle::OperatorCodeT &opcode);
+std::string opcode_name(const circle::OperatorCode *opcode);
+
const char *tensor_name(const circle::TensorT &tensor);
+const char *tensor_name(const circle::Tensor *tensor);
+
const circle::QuantizationParametersT *tensor_quantization(const circle::TensorT &tensor);
+const circle::QuantizationParameters *tensor_quantization(const circle::Tensor *tensor);
loco::DataType luci_datatype(circle::TensorType type);
FusedActFunc luci_actfunc(const circle::ActivationFunctionType type);
luci_weights_format(const circle::FullyConnectedOptionsWeightsFormat weights_format);
std::unique_ptr<CircleQuantParam>
luci_quantparam(const circle::QuantizationParametersT *quantization);
+std::unique_ptr<CircleQuantParam>
+luci_quantparam(const circle::QuantizationParameters *quantization);
/// @brief Copy common tensor attributes such as name, type, etc. to node.
void copy_tensor_attributes(const circle::TensorT &tensor, CircleNode *node);
+void copy_tensor_attributes(const circle::Tensor *tensor, CircleNode *node);
+
+/**
+ * @brief Wrapper to use flatbuffers::Vector pointer as std::vector entity
+ */
+template <typename T> class VectorWrapper
+{
+public:
+ explicit VectorWrapper(const flatbuffers::Vector<T> *ptr);
+
+ const T *data() const;
+ uint32_t size() const;
+
+ using iterator = typename flatbuffers::Vector<T>::const_iterator;
+ iterator begin() const;
+ iterator end() const;
+
+ using value_type = typename flatbuffers::Vector<T>::return_type;
+ value_type at(uint32_t i) const;
+ value_type operator[](uint32_t i) const;
+
+ bool null() const;
+ bool empty() const;
+
+private:
+ const flatbuffers::Vector<T> *_vector;
+};
+
+template <typename T> VectorWrapper<T> wrap(const flatbuffers::Vector<T> *vec)
+{
+ return VectorWrapper<T>(vec);
+}
/**
* @brief Loads Circle file and provides helpers to access attributes
*/
class CircleReader
{
-private:
+private: // unpack API
using CircleBuffers_t = std::vector<std::unique_ptr<circle::BufferT>>;
using CircleTensors_t = std::vector<std::unique_ptr<circle::TensorT>>;
using CircleOperators_t = std::vector<std::unique_ptr<circle::OperatorT>>;
using CircleOperatorCodes_t = std::vector<std::unique_ptr<circle::OperatorCodeT>>;
using CircleMetadata_t = std::vector<std::unique_ptr<circle::MetadataT>>;
+private: // direct API
+ using CircleBuffers = VectorWrapper<flatbuffers::Offset<circle::Buffer>>;
+ using CircleTensors = VectorWrapper<flatbuffers::Offset<circle::Tensor>>;
+ using CircleOperators = VectorWrapper<flatbuffers::Offset<circle::Operator>>;
+ using CircleOperatorCodes = VectorWrapper<flatbuffers::Offset<circle::OperatorCode>>;
+ using CircleMetadataSet = VectorWrapper<flatbuffers::Offset<circle::Metadata>>;
+
using CircleSubGraphsPtr_t = flatbuffers::Vector<flatbuffers::Offset<circle::SubGraph>>;
using CircleTensorsPtr_t = flatbuffers::Vector<flatbuffers::Offset<circle::Tensor>>;
public:
CircleReader() = default;
-public:
+public: // unpack API
const CircleOperatorCodes_t &opcodes() const { return _model->operator_codes; }
const CircleBuffers_t &buffers() const { return _model->buffers; }
const CircleTensors_t &tensors() const { return _current_subgraph->tensors; }
circle::BuiltinOperator builtin_code(const circle::OperatorT &op) const;
std::string opcode_name(const circle::OperatorT &op) const;
+public: // direct API
+ CircleOperatorCodes native_opcodes() const { return wrap(_native_model->operator_codes()); }
+ CircleBuffers native_buffers() const { return wrap(_native_model->buffers()); }
+ CircleTensors native_tensors() const { return wrap(_native_subgraph->tensors()); }
+ CircleOperators native_operators() const { return wrap(_native_subgraph->operators()); }
+ VectorWrapper<int32_t> native_inputs() const { return wrap(_native_subgraph->inputs()); }
+ VectorWrapper<int32_t> native_outputs() const { return wrap(_native_subgraph->outputs()); }
+ std::string native_name() const { return _native_subgraph->name()->str(); }
+ circle::DataFormat native_data_format() const { return _native_subgraph->data_format(); }
+ CircleMetadataSet native_metadata() const { return wrap(_native_model->metadata()); }
+
+ circle::BuiltinOperator builtin_code(const circle::Operator *op) const;
+ std::string opcode_name(const circle::Operator *op) const;
+
public:
bool parse(const circle::Model *model);
bool select_subgraph(uint32_t subgraph);
std::unique_ptr<const circle::ModelT> _model;
const circle::SubGraphT *_current_subgraph{nullptr};
- const circle::Model *_model_ptr{nullptr};
+ const circle::Model *_native_model{nullptr};
const CircleTensorsPtr_t *_tensors_ptr{nullptr};
+ const circle::SubGraph *_native_subgraph{nullptr};
};
} // namespace luci