[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:
John Demme 2021-12-02 05:22:57 +00:00
parent be39c7d18f
commit 7cf4f5e365
5 changed files with 22 additions and 23 deletions

View File

@ -8,7 +8,6 @@ from .devicedb import *
from .system import *
from .pycde_types import *
from .value import *
from .support import obj_to_value
from circt.support import connect
import mlir.ir

View File

@ -6,10 +6,10 @@ from __future__ import annotations
from typing import Tuple, Union, Dict
import typing
from pycde.support import obj_to_value
from pycde.support import _obj_to_value
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)
from .value import Value
@ -101,7 +101,7 @@ class _SpecializedModule:
self.loc = get_user_loc()
# 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)
# 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
generated by a previous call to said module parameterization function."""
if not isinstance(params, mlir.ir.DictAttr):
params = var_to_attribute(params)
params = _obj_to_attribute(params)
return (func, mlir.ir.Attribute(params))
@ -361,7 +361,7 @@ def _module_base(cls, extern_name: str, params={}):
else:
value = create_const_zero(type)
else:
value = obj_to_value(input, type)
value = _obj_to_value(input, type)
else:
backedge = BackedgeBuilder.current().create(type,
name,
@ -524,7 +524,7 @@ class _GeneratorPortAccess:
output_port = self._mod.output_ports[self._mod.output_port_lookup[name]]
output_port_type = output_port[1]
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:
raise ValueError("Types do not match. Output port type: "
f" '{output_port_type}'. Value type: '{value.type}'")

View File

@ -130,8 +130,8 @@ def PyCDEType(type):
def __call__(self, value_obj, name: str = None):
"""Create a Value of this type from a python object."""
from .support import obj_to_value
v = obj_to_value(value_obj, self, self)
from .support import _obj_to_value
v = _obj_to_value(value_obj, self, self)
if name is not None:
v.name = name
return v

View File

@ -6,7 +6,7 @@ import os
# 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."""
if obj is None:
return ir.BoolAttr.get(False)
@ -22,15 +22,15 @@ def var_to_attribute(obj) -> ir.Attribute:
if isinstance(obj, str):
return ir.StringAttr.get(obj)
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):
return ir.ArrayAttr.get(arr)
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)
if hasattr(obj, "__dict__"):
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)
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."""
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)
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."""
assert x is not None
from .value import Value
@ -78,7 +78,7 @@ def obj_to_value(x, type, result_type=None):
type = support.type_to_pytype(type)
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:
result_type = type
@ -106,7 +106,7 @@ def obj_to_value(x, type, result_type=None):
if len(x) != type.size:
raise ValueError("List must have same size as array "
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.
with get_user_loc():
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:
if fname not in x:
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)
if len(x) > 0:
raise ValueError(f"Extra fields specified: {x}")

View File

@ -1,7 +1,7 @@
# RUN: %PYTHON% %s | FileCheck %s
from pycde import (Output, Input, module, generator, obj_to_value, types, dim,
System, no_connect)
from pycde import (Output, Input, module, generator, types, dim, System,
no_connect)
from pycde.module import externmodule
@ -27,9 +27,9 @@ class Top:
@generator
def build(_):
obj_to_value({"foo": 7}, types.struct({"foo": types.i12}))
obj_to_value([42, 45], dim(types.i8, 2))
obj_to_value(5, types.i8)
types.struct({"foo": types.i12})({"foo": 7})
dim(types.i8, 2)([42, 45])
types.i8(5)
BarType({"foo": 7})