1# Copyright (c) Meta Platforms, Inc. and affiliates. 2# All rights reserved. 3# 4# This source code is licensed under the BSD-style license found in the 5# LICENSE file in the root directory of this source tree. 6 7# pyre-strict 8 9# TODO(T138924864): Refactor to unify the serialization for bundled program and executorch program. 10 11import json 12import os 13import tempfile 14 15import executorch.devtools.bundled_program.schema as bp_schema 16 17# @manual=fbsource//third-party/pypi/setuptools:setuptools 18import pkg_resources 19from executorch.devtools.bundled_program.core import BundledProgram 20 21from executorch.exir._serialize._dataclass import _DataclassEncoder, _json_to_dataclass 22from executorch.exir._serialize._flatbuffer import _flatc_compile, _flatc_decompile 23 24# The prefix of schema files used for bundled program 25BUNDLED_PROGRAM_SCHEMA_NAME = "bundled_program_schema" 26SCALAR_TYPE_SCHEMA_NAME = "scalar_type" 27 28 29def write_schema(d: str, schema_name: str) -> None: 30 schema_path = os.path.join(d, "{}.fbs".format(schema_name)) 31 with open(schema_path, "wb") as schema_file: 32 schema_file.write( 33 pkg_resources.resource_string(__name__, "{}.fbs".format(schema_name)) 34 ) 35 36 37def serialize_from_bundled_program_to_json( 38 bundled_program: bp_schema.BundledProgram, 39) -> str: 40 return json.dumps(bundled_program, cls=_DataclassEncoder) 41 42 43def deserialize_from_json_to_bundled_program( 44 program_json: bytes, 45) -> bp_schema.BundledProgram: 46 program_json = json.loads(program_json) 47 return _json_to_dataclass(program_json, bp_schema.BundledProgram) 48 49 50def convert_to_flatbuffer(program_json: str) -> bytes: 51 with tempfile.TemporaryDirectory() as d: 52 # load given and common schema 53 write_schema(d, BUNDLED_PROGRAM_SCHEMA_NAME) 54 write_schema(d, SCALAR_TYPE_SCHEMA_NAME) 55 56 schema_path = os.path.join(d, "{}.fbs".format(BUNDLED_PROGRAM_SCHEMA_NAME)) 57 json_path = os.path.join(d, "{}.json".format(BUNDLED_PROGRAM_SCHEMA_NAME)) 58 with open(json_path, "wb") as json_file: 59 json_file.write(program_json.encode("ascii")) 60 _flatc_compile(d, schema_path, json_path) 61 output_path = os.path.join(d, "{}.bpte".format(BUNDLED_PROGRAM_SCHEMA_NAME)) 62 with open(output_path, "rb") as output_file: 63 return output_file.read() 64 65 66def convert_from_flatbuffer(program_flatbuffer: bytes) -> bytes: 67 with tempfile.TemporaryDirectory() as d: 68 write_schema(d, BUNDLED_PROGRAM_SCHEMA_NAME) 69 write_schema(d, SCALAR_TYPE_SCHEMA_NAME) 70 71 schema_path = os.path.join(d, "{}.fbs".format(BUNDLED_PROGRAM_SCHEMA_NAME)) 72 bin_path = os.path.join(d, "schema.bin") 73 with open(bin_path, "wb") as bin_file: 74 bin_file.write(program_flatbuffer) 75 _flatc_decompile(d, schema_path, bin_path) 76 output_path = os.path.join(d, "schema.json") 77 with open(output_path, "rb") as output_file: 78 return output_file.read() 79 80 81# from bundled program to flatbuffer 82def serialize_from_bundled_program_to_flatbuffer( 83 bundled_program: BundledProgram, 84) -> bytes: 85 """ 86 Serialize a BundledProgram into FlatBuffer binary format. 87 88 Args: 89 bundled_program (BundledProgram): The `BundledProgram` variable to be serialized. 90 91 Returns: 92 The serialized FlatBuffer binary data in bytes. 93 """ 94 95 bundled_program_in_schema = bundled_program.serialize_to_schema() 96 97 return convert_to_flatbuffer( 98 serialize_from_bundled_program_to_json(bundled_program_in_schema) 99 ) 100 101 102# From flatbuffer to bundled program in schema. 103# Please notice here the bundled program is the one in our schema (bp_schema.BundledProgram), 104# not the bundled program user interact with (core.bundled_program). 105# However there're two concerns for current design: 106# 1. the misalignment of serialization input and deserialization out, which may confuse our user. 107# 2. the mis-exposion of schema.bundled_program. all classes in schema should not directly 108# interact with user, but the deserialization api returns one. 109# TODO(T170042248): Solve the above issues. 110def deserialize_from_flatbuffer_to_bundled_program( 111 flatbuffer: bytes, 112) -> bp_schema.BundledProgram: 113 """ 114 Deserialize a FlatBuffer binary format into a BundledProgram. 115 116 Args: 117 flatbuffer (bytes): The FlatBuffer binary data in bytes. 118 119 Returns: 120 A `BundledProgram` instance. 121 """ 122 return deserialize_from_json_to_bundled_program(convert_from_flatbuffer(flatbuffer)) 123