diff --git a/compiler/tflchef/core/src/ModelChef.cpp b/compiler/tflchef/core/src/ModelChef.cpp index 9cb38d9730e..842fd0e4c3a 100644 --- a/compiler/tflchef/core/src/ModelChef.cpp +++ b/compiler/tflchef/core/src/ModelChef.cpp @@ -177,27 +177,36 @@ std::set gather_customcode_set(const ::tflchef::ModelRecipe &model_ namespace { -struct ModelChef +class ModelChef { +public: + ModelChef() = default; + +public: void init(void); void cook(const ::tflchef::ModelRecipe &model_recipe); template std::map cook_graph(const T &graph); - std::unique_ptr flatbuffer_builder; +public: + const char *get_buffer_pointer(void) const; + size_t get_size(void) const; - std::vector> signdef_vec; - std::vector> buffer_vec; - std::vector> code_vec; - std::vector> subgraph_vec; - std::map builtin_code_map; - std::vector custom_code_vec; +private: + std::unique_ptr _flatbuffer_builder; + + std::vector> _signdef_vec; + std::vector> _buffer_vec; + std::vector> _code_vec; + std::vector> _subgraph_vec; + std::map _builtin_code_map; + std::vector _custom_code_vec; std::string _graph_name; }; void ModelChef::init(void) { - flatbuffer_builder = + _flatbuffer_builder = std::unique_ptr(new flatbuffers::FlatBufferBuilder(1024)); } @@ -266,22 +275,22 @@ template std::map ModelChef::cook_graph(const } }; - int32_t buffer_start = buffer_vec.size(); + int32_t buffer_start = _buffer_vec.size(); int32_t buffer_index = 0; // Create buffer(s) 1~n(I) for input(s) const auto size_input = graph.input_size(); for (int ci = 0; ci < size_input; ++ci) { - tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; - buffer_vec.emplace_back(buffer_builder.Finish()); + tflite::BufferBuilder buffer_builder{*_flatbuffer_builder}; + _buffer_vec.emplace_back(buffer_builder.Finish()); } // Create buffer(s) n(I)+1~n(I)+n(O) for output(s) const auto size_output = graph.output_size(); for (int co = 0; co < size_output; ++co) { - tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; - buffer_vec.emplace_back(buffer_builder.Finish()); + tflite::BufferBuilder buffer_builder{*_flatbuffer_builder}; + _buffer_vec.emplace_back(buffer_builder.Finish()); } auto input_names = as_dataset(graph.input()).vectorize(); @@ -300,10 +309,10 @@ template std::map ModelChef::cook_graph(const if (operand.has_shape()) { dims = as_dims(operand.shape()); - shape = flatbuffer_builder->CreateVector(dims); + shape = _flatbuffer_builder->CreateVector(dims); } - auto name = flatbuffer_builder->CreateString(operand.name()); + auto name = _flatbuffer_builder->CreateString(operand.name()); buffer_index = 0; @@ -354,31 +363,31 @@ template std::map ModelChef::cook_graph(const sparse_uint8.emplace_back(arr[b]); } } - auto data = flatbuffer_builder->CreateVector(sparse_uint8); + auto data = _flatbuffer_builder->CreateVector(sparse_uint8); // Create Buffer - tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; + tflite::BufferBuilder buffer_builder{*_flatbuffer_builder}; buffer_builder.add_data(data); auto buffer = buffer_builder.Finish(); // Update Buffer Index & Vector - buffer_index = buffer_vec.size(); - buffer_vec.emplace_back(buffer); + buffer_index = _buffer_vec.size(); + _buffer_vec.emplace_back(buffer); // save SparsityParameters - auto traversal_order = flatbuffer_builder->CreateVector(traversal_order_vec); + auto traversal_order = _flatbuffer_builder->CreateVector(traversal_order_vec); // Create block map std::vector block_map_vec{}; - auto block_map = flatbuffer_builder->CreateVector(block_map_vec); + auto block_map = _flatbuffer_builder->CreateVector(block_map_vec); // Create dimension metadata const auto &dim_metadata_src = converter.GetDimMetadata(); auto dim_metadata_vec = - make_dim_metadata_vec(flatbuffer_builder.get(), dims_count, traversal_order_vec, + make_dim_metadata_vec(_flatbuffer_builder.get(), dims_count, traversal_order_vec, format_vec, dim_metadata_src); - auto dim_metadata = flatbuffer_builder->CreateVector(dim_metadata_vec); - sparsity_index = tflite::CreateSparsityParameters(*flatbuffer_builder, traversal_order, + auto dim_metadata = _flatbuffer_builder->CreateVector(dim_metadata_vec); + sparsity_index = tflite::CreateSparsityParameters(*_flatbuffer_builder, traversal_order, block_map, dim_metadata); } else if (operand.type() == tflchef::FLOAT16) @@ -397,31 +406,31 @@ template std::map ModelChef::cook_graph(const sparse_uint8.emplace_back(arr[b]); } } - auto data = flatbuffer_builder->CreateVector(sparse_uint8); + auto data = _flatbuffer_builder->CreateVector(sparse_uint8); // Create Buffer - tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; + tflite::BufferBuilder buffer_builder{*_flatbuffer_builder}; buffer_builder.add_data(data); auto buffer = buffer_builder.Finish(); // Update Buffer Index & Vector - buffer_index = buffer_vec.size(); - buffer_vec.emplace_back(buffer); + buffer_index = _buffer_vec.size(); + _buffer_vec.emplace_back(buffer); // save SparsityParameters - auto traversal_order = flatbuffer_builder->CreateVector(traversal_order_vec); + auto traversal_order = _flatbuffer_builder->CreateVector(traversal_order_vec); // Create block map std::vector block_map_vec{}; - auto block_map = flatbuffer_builder->CreateVector(block_map_vec); + auto block_map = _flatbuffer_builder->CreateVector(block_map_vec); // Create dimension metadata const auto &dim_metadata_src = converter.GetDimMetadata(); auto dim_metadata_vec = - make_dim_metadata_vec(flatbuffer_builder.get(), dims_count, traversal_order_vec, + make_dim_metadata_vec(_flatbuffer_builder.get(), dims_count, traversal_order_vec, format_vec, dim_metadata_src); - auto dim_metadata = flatbuffer_builder->CreateVector(dim_metadata_vec); - sparsity_index = tflite::CreateSparsityParameters(*flatbuffer_builder, traversal_order, + auto dim_metadata = _flatbuffer_builder->CreateVector(dim_metadata_vec); + sparsity_index = tflite::CreateSparsityParameters(*_flatbuffer_builder, traversal_order, block_map, dim_metadata); } else @@ -446,16 +455,16 @@ template std::map ModelChef::cook_graph(const data_vec = data_packed; } - auto data = flatbuffer_builder->CreateVector(data_vec); + auto data = _flatbuffer_builder->CreateVector(data_vec); // Create Buffer - tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; + tflite::BufferBuilder buffer_builder{*_flatbuffer_builder}; buffer_builder.add_data(data); auto buffer = buffer_builder.Finish(); // Update Buffer Index & Vector - buffer_index = buffer_vec.size(); - buffer_vec.emplace_back(buffer); + buffer_index = _buffer_vec.size(); + _buffer_vec.emplace_back(buffer); } } else @@ -485,10 +494,10 @@ template std::map ModelChef::cook_graph(const if (buffer_index == 0) { // we couldn't find the buffer; create an empty buffer for this tensor - buffer_index = buffer_vec.size(); + buffer_index = _buffer_vec.size(); - tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; - buffer_vec.emplace_back(buffer_builder.Finish()); + tflite::BufferBuilder buffer_builder{*_flatbuffer_builder}; + _buffer_vec.emplace_back(buffer_builder.Finish()); } } assert(buffer_index != 0); @@ -516,13 +525,13 @@ template std::map ModelChef::cook_graph(const for (uint32_t i = 0; i < quant.zero_point_size(); ++i) quant_zero_point_vec.at(i) = quant.zero_point(i); - auto quant_max = flatbuffer_builder->CreateVector(quant_max_vec); - auto quant_min = flatbuffer_builder->CreateVector(quant_min_vec); - auto quant_scale = flatbuffer_builder->CreateVector(quant_scale_vec); - auto quant_zero_point = flatbuffer_builder->CreateVector(quant_zero_point_vec); + auto quant_max = _flatbuffer_builder->CreateVector(quant_max_vec); + auto quant_min = _flatbuffer_builder->CreateVector(quant_min_vec); + auto quant_scale = _flatbuffer_builder->CreateVector(quant_scale_vec); + auto quant_zero_point = _flatbuffer_builder->CreateVector(quant_zero_point_vec); // Create QuantizationParameters - tflite::QuantizationParametersBuilder quant_builder{*flatbuffer_builder}; + tflite::QuantizationParametersBuilder quant_builder{*_flatbuffer_builder}; quant_builder.add_max(quant_max); quant_builder.add_min(quant_min); quant_builder.add_scale(quant_scale); @@ -540,12 +549,12 @@ template std::map ModelChef::cook_graph(const // Create traversal order std::vector traversal_order_vec{sparsity.traversal_order().dim().begin(), sparsity.traversal_order().dim().end()}; - auto traversal_order = flatbuffer_builder->CreateVector(traversal_order_vec); + auto traversal_order = _flatbuffer_builder->CreateVector(traversal_order_vec); // Create block map std::vector block_map_vec{sparsity.block_map().dim().begin(), sparsity.block_map().dim().end()}; - auto block_map = flatbuffer_builder->CreateVector(block_map_vec); + auto block_map = _flatbuffer_builder->CreateVector(block_map_vec); // Create dimension metadata std::vector> dim_metadata_vec; @@ -554,13 +563,13 @@ template std::map ModelChef::cook_graph(const { // Create array segments auto tflite_array_segments = - as_tflite_sparse_index_vec(*flatbuffer_builder, dm.array_segments()); + as_tflite_sparse_index_vec(*_flatbuffer_builder, dm.array_segments()); // Create array indices auto tflite_array_indices = - as_tflite_sparse_index_vec(*flatbuffer_builder, dm.array_indices()); + as_tflite_sparse_index_vec(*_flatbuffer_builder, dm.array_indices()); - auto tflite_dim_metadata_builder = tflite::DimensionMetadataBuilder{*flatbuffer_builder}; + auto tflite_dim_metadata_builder = tflite::DimensionMetadataBuilder{*_flatbuffer_builder}; tflite_dim_metadata_builder.add_format(as_tflite_dimensiontype(dm.format())); tflite_dim_metadata_builder.add_dense_size(dm.dense_size()); tflite_dim_metadata_builder.add_array_segments(tflite_array_segments); @@ -572,9 +581,9 @@ template std::map ModelChef::cook_graph(const auto tflite_dim_metadata = tflite_dim_metadata_builder.Finish(); dim_metadata_vec.emplace_back(tflite_dim_metadata); } - auto dim_metadata = flatbuffer_builder->CreateVector(dim_metadata_vec); + auto dim_metadata = _flatbuffer_builder->CreateVector(dim_metadata_vec); - sparsity_index = tflite::CreateSparsityParameters(*flatbuffer_builder, traversal_order, + sparsity_index = tflite::CreateSparsityParameters(*_flatbuffer_builder, traversal_order, block_map, dim_metadata); } @@ -582,11 +591,11 @@ template std::map ModelChef::cook_graph(const if (operand.has_shape_signature()) { auto signature = as_dims(operand.shape_signature()); - shape_signature = flatbuffer_builder->CreateVector(signature); + shape_signature = _flatbuffer_builder->CreateVector(signature); } // Create Tensor - tflite::TensorBuilder tensor_builder{*flatbuffer_builder}; + tflite::TensorBuilder tensor_builder{*_flatbuffer_builder}; tensor_builder.add_shape(shape); tensor_builder.add_type(as_tflite_tensortype(operand.type())); @@ -624,39 +633,39 @@ template std::map ModelChef::cook_graph(const // Create 'inputs' std::vector input_vec = as_dataset(operation.input()).map(lookup).vectorize(); - auto inputs = flatbuffer_builder->CreateVector(input_vec); + auto inputs = _flatbuffer_builder->CreateVector(input_vec); // Create 'outputs' std::vector output_vec = as_dataset(operation.output()).map(lookup).vectorize(); - auto outputs = flatbuffer_builder->CreateVector(output_vec); + auto outputs = _flatbuffer_builder->CreateVector(output_vec); // Create Option - auto options = op_chef->value(*flatbuffer_builder); + auto options = op_chef->value(*_flatbuffer_builder); // Create Custom option - auto circle_custom_options = op_chef->custom_value(*flatbuffer_builder); + auto circle_custom_options = op_chef->custom_value(*_flatbuffer_builder); // Create Operator - tflite::OperatorBuilder op_builder{*flatbuffer_builder}; + tflite::OperatorBuilder op_builder{*_flatbuffer_builder}; // Note that opcode_index is an index into the operator_codes vector. // operator_codes consists of buildtin_code and custom_code, which is inserted sequentially. uint32_t opcode_index = 0; - auto op_it = builtin_code_map.find(op_chef->code()); + auto op_it = _builtin_code_map.find(op_chef->code()); // builtin operator - if (op_it != builtin_code_map.end()) + if (op_it != _builtin_code_map.end()) { - opcode_index = std::distance(builtin_code_map.begin(), op_it); + opcode_index = std::distance(_builtin_code_map.begin(), op_it); } // custom operator else { assert(not operation.custom_code().empty()); auto custom_code = operation.custom_code(); - auto op_it = std::find(custom_code_vec.begin(), custom_code_vec.end(), custom_code); - assert(op_it != custom_code_vec.end()); - opcode_index = builtin_code_map.size(); - opcode_index += std::distance(custom_code_vec.begin(), op_it); + auto op_it = std::find(_custom_code_vec.begin(), _custom_code_vec.end(), custom_code); + assert(op_it != _custom_code_vec.end()); + opcode_index = _builtin_code_map.size(); + opcode_index += std::distance(_custom_code_vec.begin(), op_it); } op_builder.add_opcode_index(opcode_index); @@ -675,13 +684,13 @@ template std::map ModelChef::cook_graph(const std::vector output_vec = as_dataset(graph.output()).map(lookup).vectorize(); // Create "SubGraph" arguments - auto tensors = flatbuffer_builder->CreateVector(tensor_vec); - auto inputs = flatbuffer_builder->CreateVector(input_vec); - auto outputs = flatbuffer_builder->CreateVector(output_vec); - auto operators = flatbuffer_builder->CreateVector(operator_vec); - auto name = flatbuffer_builder->CreateString(graph_name); + auto tensors = _flatbuffer_builder->CreateVector(tensor_vec); + auto inputs = _flatbuffer_builder->CreateVector(input_vec); + auto outputs = _flatbuffer_builder->CreateVector(output_vec); + auto operators = _flatbuffer_builder->CreateVector(operator_vec); + auto name = _flatbuffer_builder->CreateString(graph_name); - tflite::SubGraphBuilder subgraph_builder{*flatbuffer_builder}; + tflite::SubGraphBuilder subgraph_builder{*_flatbuffer_builder}; subgraph_builder.add_tensors(tensors); subgraph_builder.add_inputs(inputs); @@ -689,7 +698,7 @@ template std::map ModelChef::cook_graph(const subgraph_builder.add_operators(operators); subgraph_builder.add_name(name); - subgraph_vec.emplace_back(subgraph_builder.Finish()); + _subgraph_vec.emplace_back(subgraph_builder.Finish()); return symbol_table; } @@ -697,10 +706,10 @@ template std::map ModelChef::cook_graph(const void ModelChef::cook(const ::tflchef::ModelRecipe &model_recipe) { // Create OperatorCode with Builtin Operator - builtin_code_map = gather_builtincode_map(model_recipe); - for (auto const &opcode : builtin_code_map) + _builtin_code_map = gather_builtincode_map(model_recipe); + for (auto const &opcode : _builtin_code_map) { - tflite::OperatorCodeBuilder code_builder{*flatbuffer_builder}; + tflite::OperatorCodeBuilder code_builder{*_flatbuffer_builder}; // 127 is BuiltinOperator_PLACEHOLDER_FOR_GREATER_OP_CODES // This is the way to handle deprecated builtin code // See @@ -718,23 +727,23 @@ void ModelChef::cook(const ::tflchef::ModelRecipe &model_recipe) code_builder.add_builtin_code(opcode.first); auto code = code_builder.Finish(); // Update OperatorCode vector - code_vec.emplace_back(code); + _code_vec.emplace_back(code); } // Create OperatorCode with Custom Operator std::set custom_code_set = gather_customcode_set(model_recipe); - custom_code_vec = {custom_code_set.begin(), custom_code_set.end()}; + _custom_code_vec = {custom_code_set.begin(), custom_code_set.end()}; - for (auto opcode : custom_code_vec) + for (auto opcode : _custom_code_vec) { - auto custom_code = flatbuffer_builder->CreateString(opcode); - tflite::OperatorCodeBuilder code_builder{*flatbuffer_builder}; + auto custom_code = _flatbuffer_builder->CreateString(opcode); + tflite::OperatorCodeBuilder code_builder{*_flatbuffer_builder}; code_builder.add_deprecated_builtin_code(tflite::BuiltinOperator_CUSTOM); code_builder.add_custom_code(custom_code); code_builder.add_builtin_code(tflite::BuiltinOperator_CUSTOM); auto code = code_builder.Finish(); // Update OperatorCode vector - code_vec.emplace_back(code); + _code_vec.emplace_back(code); } // Create an Empty Buffer @@ -742,8 +751,8 @@ void ModelChef::cook(const ::tflchef::ModelRecipe &model_recipe) // Buffer 0 SHOULD be an empty buffer in TensorFlow Lite model file // (Please refer to the comment for Tensor.buffer field in schema) { - tflite::BufferBuilder buffer_builder{*flatbuffer_builder}; - buffer_vec.emplace_back(buffer_builder.Finish()); + tflite::BufferBuilder buffer_builder{*_flatbuffer_builder}; + _buffer_vec.emplace_back(buffer_builder.Finish()); } // symbol_tables stores symbol_table of each sub graph @@ -798,7 +807,7 @@ void ModelChef::cook(const ::tflchef::ModelRecipe &model_recipe) { // recipe for input TensorMap auto rec_tm_input = rec_signature_def.inputs(si); - auto name = flatbuffer_builder->CreateString(rec_tm_input.name()); + auto name = _flatbuffer_builder->CreateString(rec_tm_input.name()); uint32_t tensor_index = 0; // either tensor or tensor_index should exist assert(rec_tm_input.has_tensor() || rec_tm_input.has_tensor_index()); @@ -814,7 +823,7 @@ void ModelChef::cook(const ::tflchef::ModelRecipe &model_recipe) tensor_index = rec_tm_input.tensor_index(); } - ::tflite::TensorMapBuilder tensormap_builder{*flatbuffer_builder}; + ::tflite::TensorMapBuilder tensormap_builder{*_flatbuffer_builder}; tensormap_builder.add_name(name); tensormap_builder.add_tensor_index(tensor_index); tensormap_inputs.push_back(tensormap_builder.Finish()); @@ -823,7 +832,7 @@ void ModelChef::cook(const ::tflchef::ModelRecipe &model_recipe) for (int so = 0; so < rec_signature_def.outputs_size(); ++so) { auto rec_tm_output = rec_signature_def.outputs(so); - auto name = flatbuffer_builder->CreateString(rec_tm_output.name()); + auto name = _flatbuffer_builder->CreateString(rec_tm_output.name()); uint32_t tensor_index = 0; assert(rec_tm_output.has_tensor() || rec_tm_output.has_tensor_index()); if (rec_tm_output.has_tensor()) @@ -836,35 +845,35 @@ void ModelChef::cook(const ::tflchef::ModelRecipe &model_recipe) tensor_index = rec_tm_output.tensor_index(); } - ::tflite::TensorMapBuilder tensormap_builder{*flatbuffer_builder}; + ::tflite::TensorMapBuilder tensormap_builder{*_flatbuffer_builder}; tensormap_builder.add_name(name); tensormap_builder.add_tensor_index(tensor_index); tensormap_outputs.push_back(tensormap_builder.Finish()); } - auto inputs = flatbuffer_builder->CreateVector(tensormap_inputs); - auto outputs = flatbuffer_builder->CreateVector(tensormap_outputs); - auto signature_key = flatbuffer_builder->CreateString(rec_signature_def.signature_key()); + auto inputs = _flatbuffer_builder->CreateVector(tensormap_inputs); + auto outputs = _flatbuffer_builder->CreateVector(tensormap_outputs); + auto signature_key = _flatbuffer_builder->CreateString(rec_signature_def.signature_key()); // TODO add validation for signature_key - ::tflite::SignatureDefBuilder signature_def_builder{*flatbuffer_builder}; + ::tflite::SignatureDefBuilder signature_def_builder{*_flatbuffer_builder}; signature_def_builder.add_inputs(inputs); signature_def_builder.add_outputs(outputs); signature_def_builder.add_signature_key(signature_key); signature_def_builder.add_subgraph_index(rec_signature_def.subgraph_index()); - signdef_vec.emplace_back(signature_def_builder.Finish()); + _signdef_vec.emplace_back(signature_def_builder.Finish()); } // Create "Model" arguments - auto buffers = flatbuffer_builder->CreateVector(buffer_vec); - auto signdefs = flatbuffer_builder->CreateVector(signdef_vec); - auto operator_codes = flatbuffer_builder->CreateVector(code_vec); - auto subgraphs = flatbuffer_builder->CreateVector(subgraph_vec); - auto description = flatbuffer_builder->CreateString("Generated by tflchef"); + auto buffers = _flatbuffer_builder->CreateVector(_buffer_vec); + auto signdefs = _flatbuffer_builder->CreateVector(_signdef_vec); + auto operator_codes = _flatbuffer_builder->CreateVector(_code_vec); + auto subgraphs = _flatbuffer_builder->CreateVector(_subgraph_vec); + auto description = _flatbuffer_builder->CreateString("Generated by tflchef"); // Create "Model" - tflite::ModelBuilder model_builder{*flatbuffer_builder}; + tflite::ModelBuilder model_builder{*_flatbuffer_builder}; model_builder.add_version(3); model_builder.add_operator_codes(operator_codes); @@ -876,7 +885,19 @@ void ModelChef::cook(const ::tflchef::ModelRecipe &model_recipe) auto model = model_builder.Finish(); // Finalize - ::tflite::FinishModelBuffer(*flatbuffer_builder, model); + ::tflite::FinishModelBuffer(*_flatbuffer_builder, model); +} + +const char *ModelChef::get_buffer_pointer(void) const +{ + // + return reinterpret_cast(_flatbuffer_builder->GetBufferPointer()); +} + +size_t ModelChef::get_size(void) const +{ + // + return _flatbuffer_builder->GetSize(); } } // namespace @@ -896,14 +917,14 @@ class GeneratedModelImpl final : public tflchef::GeneratedModel::Impl const char *base(void) const override { // Return the base address of generated flatbuffer model - return reinterpret_cast(_mc.flatbuffer_builder->GetBufferPointer()); + return reinterpret_cast(_mc.get_buffer_pointer()); } public: size_t size(void) const override { // Return the size of generated flatbuffer model - return _mc.flatbuffer_builder->GetSize(); + return _mc.get_size(); } public: