Skip to content

Type conversion

type_conversion

FunctionRegistry

A mapping between Python callables and IR operation types.

Source code in xdsl/frontend/pyast/utils/type_conversion.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
class FunctionRegistry:
    """A mapping between Python callables and IR operation types."""

    def __init__(self):
        """Instantiate the function registry."""
        self._mapping: dict[Callable[..., Any], Callable[..., Operation]] = {}

    def insert(
        self, callable: Callable[..., Any], ir_constructor: Callable[..., Operation]
    ) -> None:
        """Insert a relation between a Python callable and an IR operation constructor."""
        if callable in self._mapping:
            raise FrontendProgramException(
                f"Cannot re-register function '{callable.__qualname__}'"
            )
        self._mapping[callable] = ir_constructor

    def get_operation_constructor(
        self, callable: Callable[..., Any]
    ) -> Callable[..., Operation] | None:
        """Get the IR operation constructor from a Python callable."""
        return self._mapping.get(callable, None)

    def resolve_operation(
        self,
        module_name: str,
        method_name: str,
        args: tuple[SSAValue[Attribute], ...] = tuple(),
        kwargs: dict[str, SSAValue[Attribute]] = dict(),
    ) -> Operation | None:
        """Get a concrete IR operation from a method name and its arguments."""
        # Start at the module, and walk till a method leaf is found
        method = importlib.import_module(module_name)
        for attr in method_name.split("."):
            method = getattr(method, attr, None)
        if method is None:
            return None
        assert callable(method), "Guaranteed by type signature of registration method"
        if (
            operation_constructor := self.get_operation_constructor(method)
        ) is not None:
            return operation_constructor(*args, **kwargs)
        return None

__init__()

Instantiate the function registry.

Source code in xdsl/frontend/pyast/utils/type_conversion.py
18
19
20
def __init__(self):
    """Instantiate the function registry."""
    self._mapping: dict[Callable[..., Any], Callable[..., Operation]] = {}

insert(callable: Callable[..., Any], ir_constructor: Callable[..., Operation]) -> None

Insert a relation between a Python callable and an IR operation constructor.

Source code in xdsl/frontend/pyast/utils/type_conversion.py
22
23
24
25
26
27
28
29
30
def insert(
    self, callable: Callable[..., Any], ir_constructor: Callable[..., Operation]
) -> None:
    """Insert a relation between a Python callable and an IR operation constructor."""
    if callable in self._mapping:
        raise FrontendProgramException(
            f"Cannot re-register function '{callable.__qualname__}'"
        )
    self._mapping[callable] = ir_constructor

get_operation_constructor(callable: Callable[..., Any]) -> Callable[..., Operation] | None

Get the IR operation constructor from a Python callable.

Source code in xdsl/frontend/pyast/utils/type_conversion.py
32
33
34
35
36
def get_operation_constructor(
    self, callable: Callable[..., Any]
) -> Callable[..., Operation] | None:
    """Get the IR operation constructor from a Python callable."""
    return self._mapping.get(callable, None)

resolve_operation(module_name: str, method_name: str, args: tuple[SSAValue[Attribute], ...] = tuple(), kwargs: dict[str, SSAValue[Attribute]] = dict()) -> Operation | None

Get a concrete IR operation from a method name and its arguments.

Source code in xdsl/frontend/pyast/utils/type_conversion.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def resolve_operation(
    self,
    module_name: str,
    method_name: str,
    args: tuple[SSAValue[Attribute], ...] = tuple(),
    kwargs: dict[str, SSAValue[Attribute]] = dict(),
) -> Operation | None:
    """Get a concrete IR operation from a method name and its arguments."""
    # Start at the module, and walk till a method leaf is found
    method = importlib.import_module(module_name)
    for attr in method_name.split("."):
        method = getattr(method, attr, None)
    if method is None:
        return None
    assert callable(method), "Guaranteed by type signature of registration method"
    if (
        operation_constructor := self.get_operation_constructor(method)
    ) is not None:
        return operation_constructor(*args, **kwargs)
    return None

TypeRegistry

A mapping between Python type annotations and IR type attributes.

Source code in xdsl/frontend/pyast/utils/type_conversion.py
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
class TypeRegistry:
    """A mapping between Python type annotations and IR type attributes."""

    def __init__(self):
        """Instantiate the function registry."""
        self._mapping: dict[type, TypeAttribute] = {}

    def insert(
        self,
        annotation: type,
        attribute: TypeAttribute,
    ) -> None:
        """Insert a relation between a Python type annotation and an IR type attribute."""
        if annotation in self._mapping:
            raise FrontendProgramException(
                f"Cannot re-register type name '{annotation.__qualname__}'"
            )
        if attribute in self._mapping.values():
            raise FrontendProgramException(
                f"Cannot register multiple source types for IR type '{attribute}'"
            )
        self._mapping[annotation] = attribute

    def get_annotation(self, attribute: TypeAttribute) -> type | None:
        """Get the Python type annotation from an IR type attribute.

        This supports many-to-one mappings by resolving greedily on the first
        mapping inserted.
        """
        for key, value in self._mapping.items():
            if value == attribute:
                return key
        return None

    def resolve_attribute(
        self, annotation_name: str, globals: dict[str, Any]
    ) -> TypeAttribute | None:
        """Get an IR type attribute from a string annotation."""
        annotation = cast(
            type,
            eval(annotation_name, globals, None),
        )
        return self._mapping.get(annotation, None)

__init__()

Instantiate the function registry.

Source code in xdsl/frontend/pyast/utils/type_conversion.py
63
64
65
def __init__(self):
    """Instantiate the function registry."""
    self._mapping: dict[type, TypeAttribute] = {}

insert(annotation: type, attribute: TypeAttribute) -> None

Insert a relation between a Python type annotation and an IR type attribute.

Source code in xdsl/frontend/pyast/utils/type_conversion.py
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
def insert(
    self,
    annotation: type,
    attribute: TypeAttribute,
) -> None:
    """Insert a relation between a Python type annotation and an IR type attribute."""
    if annotation in self._mapping:
        raise FrontendProgramException(
            f"Cannot re-register type name '{annotation.__qualname__}'"
        )
    if attribute in self._mapping.values():
        raise FrontendProgramException(
            f"Cannot register multiple source types for IR type '{attribute}'"
        )
    self._mapping[annotation] = attribute

get_annotation(attribute: TypeAttribute) -> type | None

Get the Python type annotation from an IR type attribute.

This supports many-to-one mappings by resolving greedily on the first mapping inserted.

Source code in xdsl/frontend/pyast/utils/type_conversion.py
83
84
85
86
87
88
89
90
91
92
def get_annotation(self, attribute: TypeAttribute) -> type | None:
    """Get the Python type annotation from an IR type attribute.

    This supports many-to-one mappings by resolving greedily on the first
    mapping inserted.
    """
    for key, value in self._mapping.items():
        if value == attribute:
            return key
    return None

resolve_attribute(annotation_name: str, globals: dict[str, Any]) -> TypeAttribute | None

Get an IR type attribute from a string annotation.

Source code in xdsl/frontend/pyast/utils/type_conversion.py
 94
 95
 96
 97
 98
 99
100
101
102
def resolve_attribute(
    self, annotation_name: str, globals: dict[str, Any]
) -> TypeAttribute | None:
    """Get an IR type attribute from a string annotation."""
    annotation = cast(
        type,
        eval(annotation_name, globals, None),
    )
    return self._mapping.get(annotation, None)

TypeConverter dataclass

Responsible for conversion of Python type hints to xDSL types.

Source code in xdsl/frontend/pyast/utils/type_conversion.py
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
@dataclass
class TypeConverter:
    """Responsible for conversion of Python type hints to xDSL types."""

    globals: dict[str, Any] = field(default_factory=dict[str, Any])
    """
    Stores all globals in the current Python program, including imports. This is
    useful because we can lookup a class which corresponds to the type
    annotation without explicitly constructing it.
    """

    type_registry: TypeRegistry = field(default_factory=TypeRegistry)
    """Mappings between source code and ir type, indexed by name."""

    function_registry: FunctionRegistry = field(default_factory=FunctionRegistry)
    """Mappings between methods on objects and their operations."""

globals: dict[str, Any] = field(default_factory=(dict[str, Any])) class-attribute instance-attribute

Stores all globals in the current Python program, including imports. This is useful because we can lookup a class which corresponds to the type annotation without explicitly constructing it.

type_registry: TypeRegistry = field(default_factory=TypeRegistry) class-attribute instance-attribute

Mappings between source code and ir type, indexed by name.

function_registry: FunctionRegistry = field(default_factory=FunctionRegistry) class-attribute instance-attribute

Mappings between methods on objects and their operations.

__init__(globals: dict[str, Any] = dict[str, Any](), type_registry: TypeRegistry = TypeRegistry(), function_registry: FunctionRegistry = FunctionRegistry()) -> None