CIRCT 21.0.0git
Loading...
Searching...
No Matches
om.py
Go to the documentation of this file.
1# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2# See https://llvm.org/LICENSE.txt for license information.
3# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5from __future__ import annotations
6
7from ._om_ops_gen import *
8from .._mlir_libs._circt._om import AnyType, Evaluator as BaseEvaluator, Object as BaseObject, List as BaseList, Tuple as BaseTuple, Map as BaseMap, BasePath as BaseBasePath, BasePathType, Path, PathType, ClassType, ReferenceAttr, ListAttr, ListType, MapAttr, OMIntegerAttr
9
10from ..ir import Attribute, Diagnostic, DiagnosticSeverity, Module, StringAttr, IntegerAttr, IntegerType
11from ..support import attribute_to_var, var_to_attribute
12
13import sys
14import logging
15from dataclasses import fields
16from typing import TYPE_CHECKING, Any, Sequence, TypeVar
17
18if TYPE_CHECKING:
19 from _typeshed.stdlib.dataclass import DataclassInstance
20
21
22# Wrap a base mlir object with high-level object.
24 # For primitives, return the Python value directly.
25 if isinstance(value, (int, float, str, bool, tuple, list, dict)):
26 return value
27
28 if isinstance(value, BaseList):
29 return List(value)
30
31 if isinstance(value, BaseTuple):
32 return Tuple(value)
33
34 if isinstance(value, BaseMap):
35 return Map(value)
36
37 if isinstance(value, BaseBasePath):
38 return BasePath(value)
39
40 if isinstance(value, Path):
41 return value
42
43 # For objects, return an Object, wrapping the base implementation.
44 assert isinstance(value, BaseObject)
45 return Object(value)
46
47
48def om_var_to_attribute(obj, none_on_fail: bool = False) -> ir.Attrbute:
49 if isinstance(obj, int):
50 return OMIntegerAttr.get(IntegerAttr.get(IntegerType.get_signless(64), obj))
51 return var_to_attribute(obj, none_on_fail)
52
53
55 # Check if the value is any of our container or custom types.
56 if isinstance(value, List):
57 return BaseList(value)
58
59 if isinstance(value, Tuple):
60 return BaseTuple(value)
61
62 if isinstance(value, Map):
63 return BaseMap(value)
64
65 if isinstance(value, BasePath):
66 return BaseBasePath(value)
67
68 if isinstance(value, Path):
69 return value
70
71 if isinstance(value, Object):
72 return BaseObject(value)
73
74 # Otherwise, it must be a primitive, so just return it.
75 return value
76
77
79
80 def __init__(self, obj: BaseList) -> None:
81 super().__init__(obj)
82
83 def __getitem__(self, i):
84 val = super().__getitem__(i)
85 return wrap_mlir_object(val)
86
87 # Support iterating over a List by yielding its elements.
88 def __iter__(self):
89 for i in range(0, self.__len__()):
90 yield self.__getitem__(i)
91
92
94
95 def __init__(self, obj: BaseTuple) -> None:
96 super().__init__(obj)
97
98 def __getitem__(self, i):
99 val = super().__getitem__(i)
100 return wrap_mlir_object(val)
101
102 # Support iterating over a Tuple by yielding its elements.
103 def __iter__(self):
104 for i in range(0, self.__len__()):
105 yield self.__getitem__(i)
106
107
109
110 def __init__(self, obj: BaseMap) -> None:
111 super().__init__(obj)
112
113 def __getitem__(self, key):
114 val = super().__getitem__(key)
115 return wrap_mlir_object(val)
116
117 def keys(self):
118 return [wrap_mlir_object(arg) for arg in super().keys()]
119
120 def items(self):
121 for i in self:
122 yield i
123
124 def values(self):
125 for (_, v) in self:
126 yield v
127
128 # Support iterating over a Map
129 def __iter__(self):
130 for i in super().keys():
131 yield (wrap_mlir_object(i), self.__getitem__(i))
132
133
135
136 @staticmethod
137 def get_empty(context=None) -> "BasePath":
138 return BasePath(BaseBasePath.get_empty(context))
139
140
141# Define the Object class by inheriting from the base implementation in C++.
143
144 def __init__(self, obj: BaseObject) -> None:
145 super().__init__(obj)
146
147 def __getattr__(self, name: str):
148 # Call the base method to get a field.
149 field = super().__getattr__(name)
150 return wrap_mlir_object(field)
151
152 def get_field_loc(self, name: str):
153 # Call the base method to get the loc.
154 loc = super().get_field_loc(name)
155 return loc
156
157 # Support iterating over an Object by yielding its fields.
158 def __iter__(self):
159 for name in self.field_names:
160 yield (name, getattr(self, name))
161
162
163# Define the Evaluator class by inheriting from the base implementation in C++.
165
166 def __init__(self, mod: Module) -> None:
167 """Instantiate an Evaluator with a Module."""
168
169 # Call the base constructor.
170 super().__init__(mod)
171
172 # Set up logging for diagnostics.
173 logging.basicConfig(
174 format="[%(asctime)s] %(name)s (%(levelname)s) %(message)s",
175 datefmt="%Y-%m-%d %H:%M:%S",
176 level=logging.INFO,
177 stream=sys.stdout,
178 )
179 self._logger = logging.getLogger("Evaluator")
180
181 # Attach our Diagnostic handler.
182 mod.context.attach_diagnostic_handler(self._handle_diagnostic_handle_diagnostic)
183
184 def instantiate(self, cls: str, *args: Any) -> Object:
185 """Instantiate an Object with a class name and actual parameters."""
186
187 # Convert the class name and actual parameters to Attributes within the
188 # Evaluator's context.
189 with self.module.context:
190 # Get the class name from the class name.
191 class_name = StringAttr.get(cls)
192
193 # Get the actual parameter Values from the supplied variadic
194 # arguments.
195 actual_params = [unwrap_python_object(arg) for arg in args]
196
197 # Call the base instantiate method.
198 obj = super().instantiate(class_name, actual_params)
199
200 # Return the Object, wrapping the base implementation.
201 return Object(obj)
202
203 def _handle_diagnostic(self, diagnostic: Diagnostic) -> bool:
204 """Handle MLIR Diagnostics by logging them."""
205
206 # Log the diagnostic message at the appropriate level.
207 if diagnostic.severity == DiagnosticSeverity.ERROR:
208 self._logger.error(diagnostic.message)
209 elif diagnostic.severity == DiagnosticSeverity.WARNING:
210 self._logger.warning(diagnostic.message)
211 else:
212 self._logger.info(diagnostic.message)
213
214 # Log any diagnostic notes at the info level.
215 for note in diagnostic.notes:
216 self._logger.info(str(note))
217
218 # Flush the stdout stream to ensure logs appear when expected.
219 sys.stdout.flush()
220
221 # Return True, indicating this diagnostic has been fully handled.
222 return True
"BasePath" get_empty(context=None)
Definition om.py:137
None __init__(self, Module mod)
Definition om.py:166
_handle_diagnostic
Definition om.py:182
bool _handle_diagnostic(self, Diagnostic diagnostic)
Definition om.py:203
Object instantiate(self, str cls, *Any args)
Definition om.py:184
Definition om.py:78
__iter__(self)
Definition om.py:88
__getitem__(self, i)
Definition om.py:83
None __init__(self, BaseList obj)
Definition om.py:80
Definition om.py:108
None __init__(self, BaseMap obj)
Definition om.py:110
values(self)
Definition om.py:124
items(self)
Definition om.py:120
keys(self)
Definition om.py:117
__iter__(self)
Definition om.py:129
__getitem__(self, key)
Definition om.py:113
__iter__(self)
Definition om.py:158
None __init__(self, BaseObject obj)
Definition om.py:144
get_field_loc(self, str name)
Definition om.py:152
__getattr__(self, str name)
Definition om.py:147
Definition om.py:93
__getitem__(self, i)
Definition om.py:98
__iter__(self)
Definition om.py:103
None __init__(self, BaseTuple obj)
Definition om.py:95
wrap_mlir_object(value)
Definition om.py:23
unwrap_python_object(value)
Definition om.py:54
ir.Attrbute om_var_to_attribute(obj, bool none_on_fail=False)
Definition om.py:48