mirror of https://github.com/llvm/circt.git
[PyCDE] Hide support functions which convert objects from Python to MLIR
The `obj_to_value` and `var_to_attribute` functions used to be publicly exposed since they had to occasionally used by users. Now that we've patched all the cases, "hide" them. Also rename to be more consistent with each other.
This commit is contained in:
parent
be39c7d18f
commit
7cf4f5e365
|
@ -8,7 +8,6 @@ from .devicedb import *
|
||||||
from .system import *
|
from .system import *
|
||||||
from .pycde_types import *
|
from .pycde_types import *
|
||||||
from .value import *
|
from .value import *
|
||||||
from .support import obj_to_value
|
|
||||||
from circt.support import connect
|
from circt.support import connect
|
||||||
|
|
||||||
import mlir.ir
|
import mlir.ir
|
||||||
|
|
|
@ -6,10 +6,10 @@ from __future__ import annotations
|
||||||
from typing import Tuple, Union, Dict
|
from typing import Tuple, Union, Dict
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from pycde.support import obj_to_value
|
from pycde.support import _obj_to_value
|
||||||
|
|
||||||
from .pycde_types import types
|
from .pycde_types import types
|
||||||
from .support import (get_user_loc, var_to_attribute, OpOperandConnect,
|
from .support import (get_user_loc, _obj_to_attribute, OpOperandConnect,
|
||||||
create_type_string, create_const_zero)
|
create_type_string, create_const_zero)
|
||||||
from .value import Value
|
from .value import Value
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ class _SpecializedModule:
|
||||||
self.loc = get_user_loc()
|
self.loc = get_user_loc()
|
||||||
|
|
||||||
# Make sure 'parameters' is a DictAttr rather than a python value.
|
# Make sure 'parameters' is a DictAttr rather than a python value.
|
||||||
self.parameters = var_to_attribute(parameters)
|
self.parameters = _obj_to_attribute(parameters)
|
||||||
assert isinstance(self.parameters, mlir.ir.DictAttr)
|
assert isinstance(self.parameters, mlir.ir.DictAttr)
|
||||||
|
|
||||||
# Get the module name
|
# Get the module name
|
||||||
|
@ -248,7 +248,7 @@ def _get_module_cache_key(func,
|
||||||
module parameterization function AND parameter values to the class which was
|
module parameterization function AND parameter values to the class which was
|
||||||
generated by a previous call to said module parameterization function."""
|
generated by a previous call to said module parameterization function."""
|
||||||
if not isinstance(params, mlir.ir.DictAttr):
|
if not isinstance(params, mlir.ir.DictAttr):
|
||||||
params = var_to_attribute(params)
|
params = _obj_to_attribute(params)
|
||||||
return (func, mlir.ir.Attribute(params))
|
return (func, mlir.ir.Attribute(params))
|
||||||
|
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ def _module_base(cls, extern_name: str, params={}):
|
||||||
else:
|
else:
|
||||||
value = create_const_zero(type)
|
value = create_const_zero(type)
|
||||||
else:
|
else:
|
||||||
value = obj_to_value(input, type)
|
value = _obj_to_value(input, type)
|
||||||
else:
|
else:
|
||||||
backedge = BackedgeBuilder.current().create(type,
|
backedge = BackedgeBuilder.current().create(type,
|
||||||
name,
|
name,
|
||||||
|
@ -524,7 +524,7 @@ class _GeneratorPortAccess:
|
||||||
output_port = self._mod.output_ports[self._mod.output_port_lookup[name]]
|
output_port = self._mod.output_ports[self._mod.output_port_lookup[name]]
|
||||||
output_port_type = output_port[1]
|
output_port_type = output_port[1]
|
||||||
if not isinstance(value, Value):
|
if not isinstance(value, Value):
|
||||||
value = obj_to_value(value, output_port_type)
|
value = _obj_to_value(value, output_port_type)
|
||||||
if value.type != output_port_type:
|
if value.type != output_port_type:
|
||||||
raise ValueError("Types do not match. Output port type: "
|
raise ValueError("Types do not match. Output port type: "
|
||||||
f" '{output_port_type}'. Value type: '{value.type}'")
|
f" '{output_port_type}'. Value type: '{value.type}'")
|
||||||
|
|
|
@ -130,8 +130,8 @@ def PyCDEType(type):
|
||||||
|
|
||||||
def __call__(self, value_obj, name: str = None):
|
def __call__(self, value_obj, name: str = None):
|
||||||
"""Create a Value of this type from a python object."""
|
"""Create a Value of this type from a python object."""
|
||||||
from .support import obj_to_value
|
from .support import _obj_to_value
|
||||||
v = obj_to_value(value_obj, self, self)
|
v = _obj_to_value(value_obj, self, self)
|
||||||
if name is not None:
|
if name is not None:
|
||||||
v.name = name
|
v.name = name
|
||||||
return v
|
return v
|
||||||
|
|
|
@ -6,7 +6,7 @@ import os
|
||||||
|
|
||||||
|
|
||||||
# PyCDE needs a custom version of this to support python classes.
|
# PyCDE needs a custom version of this to support python classes.
|
||||||
def var_to_attribute(obj) -> ir.Attribute:
|
def _obj_to_attribute(obj) -> ir.Attribute:
|
||||||
"""Create an MLIR attribute from a Python object for a few common cases."""
|
"""Create an MLIR attribute from a Python object for a few common cases."""
|
||||||
if obj is None:
|
if obj is None:
|
||||||
return ir.BoolAttr.get(False)
|
return ir.BoolAttr.get(False)
|
||||||
|
@ -22,15 +22,15 @@ def var_to_attribute(obj) -> ir.Attribute:
|
||||||
if isinstance(obj, str):
|
if isinstance(obj, str):
|
||||||
return ir.StringAttr.get(obj)
|
return ir.StringAttr.get(obj)
|
||||||
if isinstance(obj, list) or isinstance(obj, tuple):
|
if isinstance(obj, list) or isinstance(obj, tuple):
|
||||||
arr = [var_to_attribute(x) for x in obj]
|
arr = [_obj_to_attribute(x) for x in obj]
|
||||||
if all(arr):
|
if all(arr):
|
||||||
return ir.ArrayAttr.get(arr)
|
return ir.ArrayAttr.get(arr)
|
||||||
if isinstance(obj, dict):
|
if isinstance(obj, dict):
|
||||||
attrs = {name: var_to_attribute(value) for name, value in obj.items()}
|
attrs = {name: _obj_to_attribute(value) for name, value in obj.items()}
|
||||||
return ir.DictAttr.get(attrs)
|
return ir.DictAttr.get(attrs)
|
||||||
if hasattr(obj, "__dict__"):
|
if hasattr(obj, "__dict__"):
|
||||||
attrs = {
|
attrs = {
|
||||||
name: var_to_attribute(value) for name, value in obj.__dict__.items()
|
name: _obj_to_attribute(value) for name, value in obj.__dict__.items()
|
||||||
}
|
}
|
||||||
return ir.DictAttr.get(attrs)
|
return ir.DictAttr.get(attrs)
|
||||||
raise TypeError(f"Cannot convert type '{type(obj)}' to MLIR attribute. "
|
raise TypeError(f"Cannot convert type '{type(obj)}' to MLIR attribute. "
|
||||||
|
@ -66,11 +66,11 @@ class OpOperandConnect(support.OpOperand):
|
||||||
"""An OpOperand pycde extension which adds a connect method."""
|
"""An OpOperand pycde extension which adds a connect method."""
|
||||||
|
|
||||||
def connect(self, obj, result_type=None):
|
def connect(self, obj, result_type=None):
|
||||||
val = obj_to_value(obj, self.type, result_type)
|
val = _obj_to_value(obj, self.type, result_type)
|
||||||
support.connect(self, val)
|
support.connect(self, val)
|
||||||
|
|
||||||
|
|
||||||
def obj_to_value(x, type, result_type=None):
|
def _obj_to_value(x, type, result_type=None):
|
||||||
"""Convert a python object to a CIRCT value, given the CIRCT type."""
|
"""Convert a python object to a CIRCT value, given the CIRCT type."""
|
||||||
assert x is not None
|
assert x is not None
|
||||||
from .value import Value
|
from .value import Value
|
||||||
|
@ -78,7 +78,7 @@ def obj_to_value(x, type, result_type=None):
|
||||||
|
|
||||||
type = support.type_to_pytype(type)
|
type = support.type_to_pytype(type)
|
||||||
if isinstance(type, hw.TypeAliasType):
|
if isinstance(type, hw.TypeAliasType):
|
||||||
return obj_to_value(x, type.inner_type, type)
|
return _obj_to_value(x, type.inner_type, type)
|
||||||
|
|
||||||
if result_type is None:
|
if result_type is None:
|
||||||
result_type = type
|
result_type = type
|
||||||
|
@ -106,7 +106,7 @@ def obj_to_value(x, type, result_type=None):
|
||||||
if len(x) != type.size:
|
if len(x) != type.size:
|
||||||
raise ValueError("List must have same size as array "
|
raise ValueError("List must have same size as array "
|
||||||
f"{len(x)} vs {type.size}")
|
f"{len(x)} vs {type.size}")
|
||||||
list_of_vals = list(map(lambda x: obj_to_value(x, elemty), x))
|
list_of_vals = list(map(lambda x: _obj_to_value(x, elemty), x))
|
||||||
# CIRCT's ArrayCreate op takes the array in reverse order.
|
# CIRCT's ArrayCreate op takes the array in reverse order.
|
||||||
with get_user_loc():
|
with get_user_loc():
|
||||||
return hw.ArrayCreateOp(reversed(list_of_vals))
|
return hw.ArrayCreateOp(reversed(list_of_vals))
|
||||||
|
@ -119,7 +119,7 @@ def obj_to_value(x, type, result_type=None):
|
||||||
for (fname, ftype) in fields:
|
for (fname, ftype) in fields:
|
||||||
if fname not in x:
|
if fname not in x:
|
||||||
raise ValueError(f"Could not find expected field: {fname}")
|
raise ValueError(f"Could not find expected field: {fname}")
|
||||||
elem_name_values.append((fname, obj_to_value(x[fname], ftype)))
|
elem_name_values.append((fname, _obj_to_value(x[fname], ftype)))
|
||||||
x.pop(fname)
|
x.pop(fname)
|
||||||
if len(x) > 0:
|
if len(x) > 0:
|
||||||
raise ValueError(f"Extra fields specified: {x}")
|
raise ValueError(f"Extra fields specified: {x}")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# RUN: %PYTHON% %s | FileCheck %s
|
# RUN: %PYTHON% %s | FileCheck %s
|
||||||
|
|
||||||
from pycde import (Output, Input, module, generator, obj_to_value, types, dim,
|
from pycde import (Output, Input, module, generator, types, dim, System,
|
||||||
System, no_connect)
|
no_connect)
|
||||||
from pycde.module import externmodule
|
from pycde.module import externmodule
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,9 +27,9 @@ class Top:
|
||||||
|
|
||||||
@generator
|
@generator
|
||||||
def build(_):
|
def build(_):
|
||||||
obj_to_value({"foo": 7}, types.struct({"foo": types.i12}))
|
types.struct({"foo": types.i12})({"foo": 7})
|
||||||
obj_to_value([42, 45], dim(types.i8, 2))
|
dim(types.i8, 2)([42, 45])
|
||||||
obj_to_value(5, types.i8)
|
types.i8(5)
|
||||||
|
|
||||||
BarType({"foo": 7})
|
BarType({"foo": 7})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue