[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 .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

View File

@ -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}'")

View File

@ -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

View File

@ -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}")

View File

@ -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})