xref: /aosp_15_r20/external/executorch/exir/backend/test/test_compatibility.py (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
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
7import unittest
8
9import torch
10from executorch.exir import to_edge
11from executorch.exir._serialize import _serialize_pte_binary
12from executorch.exir.backend.backend_api import to_backend
13from executorch.exir.backend.compile_spec_schema import CompileSpec
14from executorch.exir.backend.test.backend_with_compiler_demo import (
15    BackendWithCompilerDemo,
16)
17
18from executorch.extension.pybindings.portable_lib import (
19    _load_for_executorch_from_buffer,  # @manual
20)
21from torch.export import export
22
23
24class TestCompatibility(unittest.TestCase):
25    def test_compatibility_in_runtime(self):
26        class SinModule(torch.nn.Module):
27            def __init__(self):
28                super().__init__()
29
30            def forward(self, x):
31                return torch.sin(x)
32
33        sin_module = SinModule()
34        model_inputs = (torch.ones(1),)
35        edgeir_m = to_edge(export(sin_module, model_inputs))
36        max_value = model_inputs[0].shape[0]
37        compile_specs = [CompileSpec("max_value", bytes([max_value]))]
38        lowered_sin_module = to_backend(
39            BackendWithCompilerDemo.__name__, edgeir_m.exported_program(), compile_specs
40        )
41        buff = lowered_sin_module.buffer()
42
43        # The demo backend works well
44        executorch_module = _load_for_executorch_from_buffer(buff)
45        model_inputs = torch.ones(1)
46        _ = executorch_module.forward([model_inputs])
47
48        prog = lowered_sin_module.program()
49        # Rewrite the delegate version number from 0 to 1.
50        prog.backend_delegate_data[0].data = bytes(
51            "1version:1#op:demo::aten.sin.default, numel:1, dtype:torch.float32<debug_handle>1#",
52            encoding="utf8",
53        )
54
55        # Generate the .pte file with the wrong version.
56        buff = bytes(
57            _serialize_pte_binary(
58                program=prog,
59            )
60        )
61
62        # Throw runtime error with error code 0x30, meaning delegate is incompatible.
63        with self.assertRaisesRegex(
64            RuntimeError,
65            "loading method forward failed with error 0x30",
66        ):
67            executorch_module = _load_for_executorch_from_buffer(buff)
68