Skip to content

Dialect loader

dialect_loader

IRDLDialectLoader

Bases: Loader

Custom module loader for IRDL files.

When loading an irdl file as a module: - parse the dialect - generate its PyRDL implementation - generate type stubs for its implmentation and write to disk - populate the Python module

Source code in xdsl/utils/dialect_loader.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
class IRDLDialectLoader(importlib.abc.Loader):
    """
    Custom module loader for IRDL files.

    When loading an irdl file as a module:
    - parse the dialect
    - generate its PyRDL implementation
    - generate type stubs for its implmentation and write to disk
    - populate the Python module
    """

    module_name: str
    path: str
    get_all_dialects: Callable[[], dict[str, Callable[[], Dialect]]]

    def __init__(
        self,
        module_name: str,
        path: str,
        get_all_dialects: Callable[[], dict[str, Callable[[], Dialect]]],
    ):
        self.module_name = module_name
        self.path = path
        self.get_all_dialects = get_all_dialects

    def exec_module(self, module: ModuleType):
        from xdsl.context import Context
        from xdsl.dialects.irdl import DialectOp
        from xdsl.interpreters.irdl import make_dialect
        from xdsl.parser import Parser

        # Open the irdl file
        with open(self.path) as file:
            # Parse it
            ctx = Context()
            for dialect_name, dialect_factory in self.get_all_dialects().items():
                ctx.register_dialect(dialect_name, dialect_factory)
            irdl_module = Parser(ctx, file.read(), self.path).parse_module()

            # Make it a PyRDL Dialect
            filename = os.path.basename(self.path)
            dialect_name, _ = os.path.splitext(filename)
            dialect_op = SymbolTable.lookup_symbol(irdl_module, dialect_name)
            assert isinstance(dialect_op, DialectOp)
            dialect = make_dialect(dialect_op)
            with open(
                f"{os.path.dirname(self.path)}/{dialect_name}.pyi", "w"
            ) as stubfile:
                print(
                    f"""\
""\"
This file is automatically generated by xDSL and not meant to be modified.

It was generated from {self.path}
""\"
""",
                    file=stubfile,
                )
                print(
                    DialectStubGenerator(dialect).generate_dialect_stubs(),
                    file=stubfile,
                )

            for obj in chain(dialect.attributes, dialect.operations):
                setattr(module, obj.__name__, obj)
            setattr(module, dialect.name.capitalize(), dialect)

module_name: str = module_name instance-attribute

path: str = path instance-attribute

get_all_dialects: Callable[[], dict[str, Callable[[], Dialect]]] = get_all_dialects instance-attribute

__init__(module_name: str, path: str, get_all_dialects: Callable[[], dict[str, Callable[[], Dialect]]])

Source code in xdsl/utils/dialect_loader.py
30
31
32
33
34
35
36
37
38
def __init__(
    self,
    module_name: str,
    path: str,
    get_all_dialects: Callable[[], dict[str, Callable[[], Dialect]]],
):
    self.module_name = module_name
    self.path = path
    self.get_all_dialects = get_all_dialects

exec_module(module: ModuleType)

Source code in xdsl/utils/dialect_loader.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    def exec_module(self, module: ModuleType):
        from xdsl.context import Context
        from xdsl.dialects.irdl import DialectOp
        from xdsl.interpreters.irdl import make_dialect
        from xdsl.parser import Parser

        # Open the irdl file
        with open(self.path) as file:
            # Parse it
            ctx = Context()
            for dialect_name, dialect_factory in self.get_all_dialects().items():
                ctx.register_dialect(dialect_name, dialect_factory)
            irdl_module = Parser(ctx, file.read(), self.path).parse_module()

            # Make it a PyRDL Dialect
            filename = os.path.basename(self.path)
            dialect_name, _ = os.path.splitext(filename)
            dialect_op = SymbolTable.lookup_symbol(irdl_module, dialect_name)
            assert isinstance(dialect_op, DialectOp)
            dialect = make_dialect(dialect_op)
            with open(
                f"{os.path.dirname(self.path)}/{dialect_name}.pyi", "w"
            ) as stubfile:
                print(
                    f"""\
""\"
This file is automatically generated by xDSL and not meant to be modified.

It was generated from {self.path}
""\"
""",
                    file=stubfile,
                )
                print(
                    DialectStubGenerator(dialect).generate_dialect_stubs(),
                    file=stubfile,
                )

            for obj in chain(dialect.attributes, dialect.operations):
                setattr(module, obj.__name__, obj)
            setattr(module, dialect.name.capitalize(), dialect)

IRDLDialectFinder

Bases: MetaPathFinder

Custom module finder for IRDL files.

Look for a .irdl file instead of a .py file.

Source code in xdsl/utils/dialect_loader.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
class IRDLDialectFinder(importlib.abc.MetaPathFinder):
    """
    Custom module finder for IRDL files.

    Look for a <name>.irdl file instead of a <name>.py file.

    """

    get_all_dialects: Callable[[], dict[str, Callable[[], Dialect]]]

    def __init__(
        self, get_all_dialects: Callable[[], dict[str, Callable[[], Dialect]]]
    ) -> None:
        super().__init__()
        self.get_all_dialects = get_all_dialects

    def find_spec(self, fullname: str, path: Sequence[str] | None, target: Any = None):
        # Check if module is already loaded and return it if so
        if fullname in sys.modules:
            return sys.modules[fullname].__spec__

        # Look for the file
        filename = fullname.split(".")[-1] + ".irdl"
        if path is None:
            path = [os.getcwd()]
        for entry in path:
            potential_path = os.path.join(entry, filename)
            if os.path.isfile(potential_path):
                # If found, create the right loader and return it
                loader = IRDLDialectLoader(
                    fullname, potential_path, self.get_all_dialects
                )
                return importlib.util.spec_from_file_location(
                    fullname, potential_path, loader=loader
                )

        # Return None if not found to let importlib do its thing.
        return None

get_all_dialects: Callable[[], dict[str, Callable[[], Dialect]]] = get_all_dialects instance-attribute

__init__(get_all_dialects: Callable[[], dict[str, Callable[[], Dialect]]]) -> None

Source code in xdsl/utils/dialect_loader.py
93
94
95
96
97
def __init__(
    self, get_all_dialects: Callable[[], dict[str, Callable[[], Dialect]]]
) -> None:
    super().__init__()
    self.get_all_dialects = get_all_dialects

find_spec(fullname: str, path: Sequence[str] | None, target: Any = None)

Source code in xdsl/utils/dialect_loader.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
def find_spec(self, fullname: str, path: Sequence[str] | None, target: Any = None):
    # Check if module is already loaded and return it if so
    if fullname in sys.modules:
        return sys.modules[fullname].__spec__

    # Look for the file
    filename = fullname.split(".")[-1] + ".irdl"
    if path is None:
        path = [os.getcwd()]
    for entry in path:
        potential_path = os.path.join(entry, filename)
        if os.path.isfile(potential_path):
            # If found, create the right loader and return it
            loader = IRDLDialectLoader(
                fullname, potential_path, self.get_all_dialects
            )
            return importlib.util.spec_from_file_location(
                fullname, potential_path, loader=loader
            )

    # Return None if not found to let importlib do its thing.
    return None