diff --git a/backends/test/harness/stages/to_edge_transform_and_lower.py b/backends/test/harness/stages/to_edge_transform_and_lower.py index 0949b633c5d..16b5ad086aa 100644 --- a/backends/test/harness/stages/to_edge_transform_and_lower.py +++ b/backends/test/harness/stages/to_edge_transform_and_lower.py @@ -14,11 +14,15 @@ class ToEdgeTransformAndLower(Stage): def __init__( self, - default_partitioner_cls: Type, + default_partitioner_cls: Type | None = None, partitioners: Optional[List[Partitioner]] = None, edge_compile_config: Optional[EdgeCompileConfig] = None, ): - self.partitioners = partitioners or [default_partitioner_cls()] + self.partitioners = ( + partitioners or [default_partitioner_cls()] + if default_partitioner_cls is not None + else [] + ) self.edge_compile_conf = edge_compile_config or EdgeCompileConfig() self.edge_dialect_program = None diff --git a/backends/test/harness/tester.py b/backends/test/harness/tester.py index 7e5b558aff0..351bab4a605 100644 --- a/backends/test/harness/tester.py +++ b/backends/test/harness/tester.py @@ -34,12 +34,12 @@ def __init__( self, module: torch.nn.Module, example_inputs: Tuple[torch.Tensor], - stage_classes: Dict[StageType, Callable], + stage_classes: Dict[StageType, Callable] | None = None, dynamic_shapes: Optional[Tuple[Any]] = None, ): module.eval() - self.stage_classes = stage_classes + self.stage_classes = stage_classes or Tester.default_stage_classes() self.original_module = module self.example_inputs = example_inputs self.dynamic_shapes = dynamic_shapes diff --git a/backends/test/suite/flow.py b/backends/test/suite/flow.py index 124891fc541..4324db46796 100644 --- a/backends/test/suite/flow.py +++ b/backends/test/suite/flow.py @@ -26,16 +26,25 @@ class TestFlow: tester_factory: Callable[..., Tester] """ A factory function that returns a Tester instance for this lowering flow. """ - quantize: bool = field(default=False) + quantize: bool = False """ Whether to tester should run the quantize stage on the model. """ quantize_stage_factory: Callable[..., Quantize] | None = None """ A factory function which instantiates a Quantize stage. Can be None to use the tester's default. """ + is_delegated: bool = True + """ Indicates whether the flow is expected to generate CALL_DELEGATE nodes. """ + def all_flows() -> dict[str, TestFlow]: flows = [] + from executorch.backends.test.suite.flows.portable import PORTABLE_TEST_FLOW + + flows += [ + PORTABLE_TEST_FLOW, + ] + try: from executorch.backends.test.suite.flows.xnnpack import ( XNNPACK_STATIC_INT8_PER_CHANNEL_TEST_FLOW, diff --git a/backends/test/suite/flows/portable.py b/backends/test/suite/flows/portable.py new file mode 100644 index 00000000000..ab176fb0e2d --- /dev/null +++ b/backends/test/suite/flows/portable.py @@ -0,0 +1,19 @@ +import logging + +from executorch.backends.test.harness import Tester +from executorch.backends.test.suite.flow import TestFlow + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) + + +def _create_portable_flow() -> TestFlow: + return TestFlow( + "portable", + backend="portable", + tester_factory=Tester, + is_delegated=False, + ) + + +PORTABLE_TEST_FLOW = _create_portable_flow() diff --git a/backends/test/suite/runner.py b/backends/test/suite/runner.py index 1d03bcf78db..5e4f1dcf32a 100644 --- a/backends/test/suite/runner.py +++ b/backends/test/suite/runner.py @@ -125,8 +125,8 @@ def build_result( if n.op == "call_function" ) - # Only run the runtime portion if something was delegated. - if is_delegated: + # Only run the runtime portion if something was delegated (or the flow doesn't delegate). + if is_delegated or not flow.is_delegated: try: tester.to_executorch().serialize() extra_stats["pte_size_bytes"] = len(tester.get_artifact())