33# This source code is licensed under the BSD-style license found in the
44# LICENSE file in the root directory of this source tree.
55
6+ import importlib .resources as _resources
67import json
78import logging
89import os
910import re
1011import shutil
1112import subprocess # nosec B404 - invoked only for trusted toolchain binaries
1213import tempfile
13-
1414from pathlib import Path
1515
1616from types import NoneType
1717from typing import Any , cast , Dict , List , Optional , Tuple
1818
19+ import executorch .backends .arm .test as arm_test_package
20+ import executorch .backends .arm .tosa .schemas as tosa_schemas_package
21+
1922import numpy as np
2023import torch
2124from executorch .backends .arm ._passes .arm_pass_utils import get_first_fake_tensor
@@ -583,6 +586,38 @@ def _run_cmd(cmd: List[str], check=True) -> subprocess.CompletedProcess[bytes]:
583586 )
584587
585588
589+ # Name of an optional resource containing the `flatc` executable.
590+ _FLATC_RESOURCE_NAME : str = "flatbuffers-flatc"
591+
592+
593+ def _run_flatc (args : List [str ]) -> None :
594+ """Runs the `flatc` command with the provided args.
595+
596+ If a resource matching _FLATC_RESOURCE_NAME exists, uses that executable.
597+ Otherwise, expects the `flatc` tool to be available on the system path.
598+ """
599+ flatc_resource = _resources .files (arm_test_package ).joinpath (_FLATC_RESOURCE_NAME )
600+ if flatc_resource .is_file ():
601+ # Use the provided flatc binary from resources.
602+ with _resources .as_file (flatc_resource ) as flatc_path :
603+ subprocess .run ( # nosec B603 - cmd constructed from trusted inputs
604+ [str (flatc_path )] + args , check = True
605+ )
606+ else :
607+ # Expect the `flatc` tool to be on the system path or set as an env var.
608+ flatc_executable : str | None = os .getenv ("FLATC_EXECUTABLE" )
609+ if not flatc_executable :
610+ flatc_executable = shutil .which ("flatc" )
611+ if not flatc_executable :
612+ raise RuntimeError (
613+ "flatc not found. Either add it to PATH, set FLATC_EXECUTABLE env var, "
614+ "or ensure the flatbuffers-flatc resource is available."
615+ )
616+ subprocess .run ( # nosec B603 - cmd constructed from trusted inputs
617+ [flatc_executable ] + args , check = True
618+ )
619+
620+
586621def dbg_tosa_fb_to_json (tosa_fb : bytes ) -> Dict :
587622 """
588623 This function is used to dump the TOSA flatbuffer to a human readable
@@ -603,16 +638,14 @@ def dbg_tosa_fb_to_json(tosa_fb: bytes) -> Dict:
603638 f"Unsupported version in TOSA flatbuffer: version={ major } .{ minor } .{ patch } "
604639 )
605640
606- arm_backend_path = os .path .realpath (os .path .dirname (__file__ ) + "/.." )
607- tosa_schema_file = os .path .join (
608- arm_backend_path , f"tosa/schemas/tosa_{ major } .{ minor } .fbs"
609- )
610- assert os .path .exists (
611- tosa_schema_file
612- ), f"tosa_schema_file: { tosa_schema_file } does not exist"
613- assert shutil .which ("flatc" ) is not None
614- cmd_flatc = [
615- "flatc" ,
641+ # Write schema file to temp directory using importlib.resources
642+ tosa_schema_file = os .path .join (tmp , f"tosa_{ major } .{ minor } .fbs" )
643+ with open (tosa_schema_file , "wb" ) as schema_file :
644+ schema_file .write (
645+ _resources .read_binary (tosa_schemas_package , f"tosa_{ major } .{ minor } .fbs" )
646+ )
647+
648+ flatc_args = [
616649 "--json" ,
617650 "--strict-json" ,
618651 "-o" ,
@@ -623,7 +656,7 @@ def dbg_tosa_fb_to_json(tosa_fb: bytes) -> Dict:
623656 "--" ,
624657 tosa_input_file ,
625658 ]
626- _run_cmd ( cmd_flatc )
659+ _run_flatc ( flatc_args )
627660 with open (os .path .join (tmp , "output.json" ), "r" ) as f :
628661 json_out = json .load (f )
629662
0 commit comments