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