| 964 | } // namespace |
| 965 | |
| 966 | OwningModuleRef tflite::FlatBufferToMlir( |
| 967 | absl::string_view buffer, MLIRContext* context, Location base_loc, |
| 968 | bool use_external_constant, |
| 969 | const std::vector<std::string>& ordered_input_arrays, |
| 970 | const std::vector<std::string>& ordered_output_arrays, |
| 971 | bool experimental_prune_unreachable_nodes_unconditionally) { |
| 972 | auto model_ptr = |
| 973 | FlatBufferModel::VerifyAndBuildFromBuffer(buffer.data(), buffer.length()); |
| 974 | if (nullptr == model_ptr) { |
| 975 | return emitError(base_loc, "couldn't parse flatbuffer"), nullptr; |
| 976 | } |
| 977 | |
| 978 | std::unique_ptr<ModelT> model(model_ptr->GetModel()->UnPack()); |
| 979 | |
| 980 | auto builder = Builder(context); |
| 981 | |
| 982 | std::vector<std::string> operator_names; |
| 983 | operator_names.reserve(model->operator_codes.size()); |
| 984 | |
| 985 | for (auto& opcode : model->operator_codes) { |
| 986 | auto operator_name_or_error = OpNameForOpCode(*opcode); |
| 987 | if (!operator_name_or_error.ok()) { |
| 988 | return emitError(base_loc, operator_name_or_error.status().ToString()), |
| 989 | nullptr; |
| 990 | } |
| 991 | operator_names.push_back(operator_name_or_error.ConsumeValueOrDie()); |
| 992 | } |
| 993 | |
| 994 | std::vector<std::string> func_names; |
| 995 | for (auto& subgraph : model->subgraphs) { |
| 996 | func_names.push_back(subgraph->name); |
| 997 | } |
| 998 | |
| 999 | auto module = mlir::ModuleOp::create(base_loc); |
| 1000 | // We currently don't use this to make decisions, but we could |
| 1001 | // use it in exports or if there are breaking changes |
| 1002 | module.setAttr("tfl.schema_version", |
| 1003 | builder.getI32IntegerAttr(model->version)); |
| 1004 | if (!model->description.empty()) { |
| 1005 | module.setAttr("tfl.description", |
| 1006 | builder.getStringAttr(model->description)); |
| 1007 | } |
| 1008 | |
| 1009 | for (auto e : llvm::enumerate(model->subgraphs)) { |
| 1010 | auto& subgraph = e.value(); |
| 1011 | std::string name = SubgraphName(e.index(), *subgraph); |
| 1012 | auto func_or_error = ConvertSubgraph( |
| 1013 | *subgraph, name, operator_names, func_names, model->buffers, base_loc, |
| 1014 | builder, |
| 1015 | // TODO(b/131175224,b/132239787) Support multiple entry points |
| 1016 | /*is_entry_point=*/e.index() == 0, |
| 1017 | /*use_external_constant=*/use_external_constant, ordered_input_arrays, |
| 1018 | ordered_output_arrays, |
| 1019 | experimental_prune_unreachable_nodes_unconditionally); |
| 1020 | if (!func_or_error.ok()) { |
| 1021 | return emitError(base_loc, "could not translate function ") |
| 1022 | << subgraph->name << ": " |
| 1023 | << func_or_error.status().error_message(), |
nothing calls this directly
no test coverage detected