Skip to content

Commit 3040dc3

Browse files
committed
exir: remove JSON program conversion path
Change-Id: Iebb6ff9151b76b352ef5dbb4d9bd23e2e622c326 Signed-off-by: Chizkiyahu Raful <chizkiyahu.raful@arm.com>
1 parent 3ceb72b commit 3040dc3

4 files changed

Lines changed: 3 additions & 192 deletions

File tree

exir/_serialize/_flatbuffer.py

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import importlib.resources
1313
import os
1414
import re
15-
import shutil
1615
import stat
1716
import subprocess
1817
import tempfile
@@ -384,72 +383,6 @@ def _flatc_decompile(
384383
)
385384

386385

387-
def _program_json_to_flatbuffer(
388-
program_json: str,
389-
*,
390-
constant_tensor_alignment: Optional[int] = None,
391-
delegate_alignment: Optional[int] = None,
392-
) -> _FlatbufferResult:
393-
"""Converts Program-compatible JSON into binary flatbuffer data.
394-
395-
Args:
396-
program_json: The JSON to convert. Must be compatible with the root
397-
table type of //executorch/schema/program.fbs.
398-
constant_tensor_alignment: If provided, the alignment to use for tensor
399-
data embedded in the output flatbuffer data. If not provided, uses
400-
the alignment in the schema.
401-
delegate_alignment: If provided, the alignment to use for delegate
402-
data embedded in the output flatbuffer data. If not provided, uses
403-
the alignment in the schema.
404-
405-
Returns: The flatbuffer data and associated metadata.
406-
"""
407-
with tempfile.TemporaryDirectory() as temp_dir:
408-
schema_info = _prepare_schema(
409-
out_dir=temp_dir,
410-
constant_tensor_alignment=constant_tensor_alignment,
411-
delegate_alignment=delegate_alignment,
412-
)
413-
file_stem = "data"
414-
json_path = os.path.join(temp_dir, file_stem + ".json")
415-
output_path = os.path.join(temp_dir, file_stem + ".pte")
416-
417-
with open(json_path, "wb") as json_file:
418-
json_file.write(program_json.encode("ascii"))
419-
420-
try:
421-
_flatc_compile(temp_dir, schema_info.root_path, json_path)
422-
except Exception as err:
423-
# It's helpful to save the breaking files for debugging. Optionally
424-
# move them out of the auto-deleting temporary directory. Don't do
425-
# this by default because some input files can be many GB in size,
426-
# and these copies won't be auto-deleted.
427-
should_save = os.getenv(_SAVE_FLATC_ENV, "").strip() not in {"", "0"}
428-
extra_message = ""
429-
if should_save:
430-
try:
431-
saved_dir = tempfile.mkdtemp(prefix="exir-saved-flatc-")
432-
for f in os.listdir(temp_dir):
433-
shutil.move(src=os.path.join(temp_dir, f), dst=saved_dir)
434-
extra_message += f" Moved input files to '{saved_dir}'."
435-
except Exception as err2:
436-
extra_message += (
437-
f" (Failed to save input files for debugging: {err2})"
438-
)
439-
else:
440-
extra_message += (
441-
f" Set {_SAVE_FLATC_ENV}=1 to save input files on failure."
442-
)
443-
444-
raise RuntimeError(
445-
f"Failed to compile {json_path} to {output_path}." + extra_message
446-
) from err
447-
with open(output_path, "rb") as output_file:
448-
return _FlatbufferResult(
449-
data=output_file.read(), max_alignment=schema_info.max_alignment
450-
)
451-
452-
453386
def _replace_infinity_in_json_file(content: bytes) -> bytes:
454387
"""Replace -inf and inf with "inf" and "-inf" in the JSON file. program.fbs
455388
is used to convert from flatbuffer to JSON. +-inf float values are not

exir/_serialize/_program.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from typing import ClassVar, Dict, List, Literal, Optional, Sequence, Tuple
1717

1818
from executorch.exir._serialize._cord import Cord
19-
from executorch.exir._serialize._dataclass import _DataclassEncoder, _json_to_dataclass
19+
from executorch.exir._serialize._dataclass import _DataclassEncoder
2020
from executorch.exir._serialize._flatbuffer import _FlatbufferResult
2121
from executorch.exir._serialize._flatbuffer_program import (
2222
_flatbuffer_to_program,
@@ -86,12 +86,6 @@ def _program_to_json(program: Program) -> str:
8686
return json.dumps(program, cls=_DataclassEncoder)
8787

8888

89-
def _json_to_program(program_json: bytes) -> Program:
90-
"""Returns a Program deserialized from the given JSON string."""
91-
# construct program class recursively from dict
92-
return _json_to_dataclass(json.loads(program_json), cls=Program)
93-
94-
9589
def _insert_flatbuffer_header(
9690
flatbuffer_data: bytes, magic_regex: str, header_data: bytes
9791
) -> bytes:
@@ -797,9 +791,7 @@ def _extract_delegate_payload(
797791
program_size = len(pte_data)
798792

799793
# Parse the program flatbuffer
800-
program: Program = _json_to_program(
801-
_program_flatbuffer_to_json(pte_data[:program_size])
802-
)
794+
program: Program = _flatbuffer_to_program(pte_data[:program_size])
803795

804796
# Search for the matching delegate
805797
match_count = 0

exir/_serialize/test/test_flatbuffer.py

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,13 @@
77
# LICENSE file in the root directory of this source tree.
88

99
import os
10-
import re
11-
import shutil
1210
import tempfile
1311
import unittest
1412
from typing import Dict, Optional, Sequence
1513
from unittest.mock import patch
1614

1715
from executorch.exir._serialize import _flatbuffer
18-
from executorch.exir._serialize._flatbuffer import (
19-
_program_json_to_flatbuffer,
20-
_ResourceFiles,
21-
_SchemaInfo,
22-
)
16+
from executorch.exir._serialize._flatbuffer import _ResourceFiles, _SchemaInfo
2317

2418

2519
def read_file(dir: str, filename: str) -> bytes:
@@ -277,60 +271,3 @@ def test_bad_delegate_alignment_fails(self) -> None:
277271
out_dir,
278272
delegate_alignment=bad_alignment,
279273
)
280-
281-
282-
class TestProgramJsonToFlatbuffer(unittest.TestCase):
283-
@patch.dict(os.environ, {_flatbuffer._SAVE_FLATC_ENV: "1"})
284-
def test_save_json_on_failure(self) -> None:
285-
err_msg: Optional[str] = None
286-
try:
287-
_program_json_to_flatbuffer("} some bad json {")
288-
self.fail("Should have raised an exception")
289-
except RuntimeError as err:
290-
err_msg = err.args[0]
291-
292-
self.assertIsNotNone(err_msg)
293-
match = re.search(r"Moved input files to '(.*?)'", err_msg)
294-
self.assertTrue(match, msg=f"Unexpected error message: {err_msg}")
295-
path = match.group(1)
296-
297-
files = frozenset(os.listdir(path))
298-
# Delete the files otherwise they'll accumulate every time the
299-
# test is run.
300-
shutil.rmtree(path)
301-
# Check for a couple of the files that should be there.
302-
self.assertIn("data.json", files)
303-
self.assertIn("program.fbs", files)
304-
305-
@patch.dict(os.environ, {_flatbuffer._SAVE_FLATC_ENV: "1"})
306-
def test_unable_to_save_json_on_failure(self) -> None:
307-
err_msg: Optional[str] = None
308-
try:
309-
with patch.object(
310-
_flatbuffer.shutil,
311-
"move",
312-
side_effect=Exception("shutil.move mock failure"),
313-
):
314-
_program_json_to_flatbuffer("} some bad json {")
315-
self.fail("Should have raised an exception")
316-
except RuntimeError as err:
317-
err_msg = err.args[0]
318-
319-
self.assertIsNotNone(err_msg)
320-
self.assertIn("Failed to save input files", err_msg)
321-
322-
@patch.dict(os.environ, {_flatbuffer._SAVE_FLATC_ENV: ""})
323-
def test_no_save_json_on_failure(self) -> None:
324-
err_msg: Optional[str] = None
325-
try:
326-
_program_json_to_flatbuffer("} some bad json {")
327-
self.fail("Should have raised an exception")
328-
except RuntimeError as err:
329-
err_msg = err.args[0]
330-
331-
self.assertIsNotNone(err_msg)
332-
self.assertIn(
333-
f"Set {_flatbuffer._SAVE_FLATC_ENV}=1 to save input files", err_msg
334-
)
335-
self.assertNotIn("Moved input files", err_msg)
336-
self.assertNotIn("Failed to save input files", err_msg)

exir/_serialize/test/test_flatbuffer_program.py

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,12 @@
44
# This source code is licensed under the BSD-style license found in the
55
# LICENSE file in the root directory of this source tree.
66

7-
import json
87
import unittest
98

10-
from executorch.exir._serialize._flatbuffer import (
11-
_program_flatbuffer_to_json,
12-
_program_json_to_flatbuffer,
13-
)
149
from executorch.exir._serialize._flatbuffer_program import (
1510
_flatbuffer_to_program,
1611
_program_to_flatbuffer,
1712
)
18-
from executorch.exir._serialize._program import _json_to_program, _program_to_json
1913
from executorch.exir.backend.compile_spec_schema import CompileSpec
2014
from executorch.exir.schema import (
2115
AllocationDetails,
@@ -160,58 +154,13 @@ def _make_program(self) -> Program:
160154
named_data=[],
161155
)
162156

163-
def _flatbuffer_to_dict(self, flatbuffer_data: bytes) -> dict:
164-
return json.loads(_program_flatbuffer_to_json(flatbuffer_data))
165-
166-
def test_roundtrip_via_json(self) -> None:
167-
program = self._make_program()
168-
result = _program_to_flatbuffer(
169-
program, constant_tensor_alignment=32, delegate_alignment=64
170-
)
171-
self.assertGreater(len(result.data), 8)
172-
self.assertEqual(result.data[4:6], b"ET")
173-
self.assertGreaterEqual(result.max_alignment, 64)
174-
175-
program2 = _json_to_program(_program_flatbuffer_to_json(result.data))
176-
self.assertEqual(program2, program)
177-
178157
def test_roundtrip_via_direct_python(self) -> None:
179158
program = self._make_program()
180159
result = _program_to_flatbuffer(
181160
program, constant_tensor_alignment=32, delegate_alignment=64
182161
)
183162
self.assertEqual(_flatbuffer_to_program(result.data), program)
184163

185-
def test_flatbuffer_paths_match(self) -> None:
186-
program = self._make_program()
187-
cases = [
188-
(None, None),
189-
(32, 64),
190-
]
191-
for constant_tensor_alignment, delegate_alignment in cases:
192-
with self.subTest(
193-
constant_tensor_alignment=constant_tensor_alignment,
194-
delegate_alignment=delegate_alignment,
195-
):
196-
result = _program_to_flatbuffer(
197-
program,
198-
constant_tensor_alignment=constant_tensor_alignment,
199-
delegate_alignment=delegate_alignment,
200-
)
201-
result2 = _program_json_to_flatbuffer(
202-
_program_to_json(program),
203-
constant_tensor_alignment=constant_tensor_alignment,
204-
delegate_alignment=delegate_alignment,
205-
)
206-
direct_dict = self._flatbuffer_to_dict(result.data)
207-
json_path_dict = self._flatbuffer_to_dict(result2.data)
208-
self.assertEqual(
209-
direct_dict,
210-
json_path_dict,
211-
"Flatbuffer JSON differs between direct and JSON paths",
212-
)
213-
self.assertEqual(result.max_alignment, result2.max_alignment)
214-
215164
def test_bad_alignment_fails(self) -> None:
216165
program = Program(
217166
version=0,

0 commit comments

Comments
 (0)