Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
fe6f2d9
fix missing nargs
kaihsin Oct 8, 2025
604317b
Add Dialect_Lookup to SerializationContext and correctly import diale…
zhenrongliew Oct 9, 2025
9e1954d
Deserialization now takes in DialectGroup. Updated tests to reflect c…
zhenrongliew Oct 9, 2025
69884ff
remove calling test
zhenrongliew Oct 9, 2025
7a0768b
tmp
kaihsin Oct 9, 2025
ee69054
Refactor Deserializer and Serializer: remove serializing specific obj…
zhenrongliew Oct 9, 2025
c7ad51c
remove print
zhenrongliew Oct 9, 2025
fa41c7e
remove handling signature from (de)serializer
zhenrongliew Oct 9, 2025
45fa9b9
tmp
kaihsin Oct 9, 2025
3198822
temp
zhenrongliew Oct 9, 2025
b64cbc2
fix import
kaihsin Oct 9, 2025
c8b41bc
refactor serialization kinds to use 'type-attribute' for consistency.…
zhenrongliew Oct 9, 2025
24792e1
Uncomment tests
zhenrongliew Oct 9, 2025
228b76e
Put guard for serializing unsupported types
zhenrongliew Oct 9, 2025
495427a
Add encoding methods to DialectGroup and update serialization tests t…
zhenrongliew Oct 9, 2025
0ed50c5
edge ir.Method with code being lambda
kaihsin Oct 9, 2025
7b2ef00
PyAttr should just check if its data is Serializable not just ir.Method.
zhenrongliew Oct 10, 2025
b340259
Removed closure serialization test. We do not want to support seriali…
zhenrongliew Oct 10, 2025
de37d83
Fixed typo checking "serialize_" instead of "deserialize_" before cal…
zhenrongliew Oct 14, 2025
e2809dd
Add co-author
zhenrongliew Oct 14, 2025
6f1b8dd
Added (de)serialize for method.fields
zhenrongliew Oct 14, 2025
6056ef4
add test
kaihsin Oct 14, 2025
37b7241
add test
kaihsin Oct 14, 2025
e0aa175
remove redundant print
kaihsin Oct 14, 2025
e1ddcdf
address PR comments: remove prints and added init=false to Serializer…
zhenrongliew Oct 14, 2025
5cb4513
remove reudndant print
kaihsin Oct 14, 2025
2a720ff
Merge branch 'khwu/fix_serialization' of https://github.com/QuEraComp…
kaihsin Oct 14, 2025
12c655b
initiliazing Methods during deserialization should set empty backedge…
zhenrongliew Oct 15, 2025
5dd3581
Check if invoked subroutine's dialect group is the subset of interpre…
zhenrongliew Oct 17, 2025
5b80bff
check if type is serializeable in Literal
neelay893 Oct 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions src/kirin/dialects/func/attrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from kirin import types
from kirin.ir import Method, Attribute
from kirin.print.printer import Printer
from kirin.serialization.core.serializationunit import SerializationUnit

if TYPE_CHECKING:
from kirin.serialization.base.serializationunit import SerializationUnit
from kirin.serialization.base.serializer import Serializer
from kirin.serialization.base.deserializer import Deserializer

Expand Down Expand Up @@ -50,7 +50,15 @@ def __eq__(self, value: object) -> bool:
return self.inputs == value.inputs and self.output == value.output

def serialize(self, serializer: "Serializer") -> "SerializationUnit":
return serializer.serialize_signature(self)
return SerializationUnit(
kind="signature",
module_name=self.__module__,
class_name=self.__class__.__name__,
data={
"inputs": serializer.serialize_tuple(self.inputs),
"output": serializer.serialize(self.output),
},
)

def is_structurally_equal(
self,
Expand All @@ -63,4 +71,6 @@ def is_structurally_equal(
def deserialize(
cls, serUnit: "SerializationUnit", deserializer: "Deserializer"
) -> "Signature":
return deserializer.deserialize_signature(serUnit)
inputs = deserializer.deserialize(serUnit.data["inputs"])
output = deserializer.deserialize(serUnit.data["output"])
return Signature(inputs=inputs, output=output)
26 changes: 19 additions & 7 deletions src/kirin/dialects/ilist/runtime.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
# TODO: replace with something faster
from typing import TYPE_CHECKING, Any, Generic, TypeVar, overload
from typing import Any, Generic, TypeVar, overload
from dataclasses import dataclass
from collections.abc import Sequence

from kirin import ir, types
from kirin.print.printer import Printer
from kirin.serialization.base.serializer import Serializer
from kirin.serialization.base.deserializer import Deserializer
from kirin.serialization.core.serializationunit import SerializationUnit

if TYPE_CHECKING:
from kirin.serialization.base.serializer import Serializer
from kirin.serialization.base.deserializer import Deserializer
from kirin.serialization.base.serializationunit import SerializationUnit
from ._dialect import dialect

T = TypeVar("T")
L = TypeVar("L")


@dataclass
@dialect.register
class IList(ir.Data[Sequence[T]], Sequence[T], Generic[T, L]):
"""A simple immutable list."""

name = "IList"
data: Sequence[T]
elem: types.TypeAttribute = types.Any

Expand Down Expand Up @@ -105,10 +107,20 @@ def is_structurally_equal(
)

def serialize(self, serializer: "Serializer") -> "SerializationUnit":
return serializer.serialize_ilist(self)
return SerializationUnit(
kind="ilist",
module_name=dialect.name,
class_name=IList.__name__,
data={
"data": serializer.serialize(self.data),
"elem": serializer.serialize_attribute(self.elem),
},
)

@classmethod
def deserialize(
cls, serUnit: "SerializationUnit", deserializer: "Deserializer"
) -> "IList":
return deserializer.deserialize_ilist(serUnit)
items = deserializer.deserialize(serUnit.data["data"])
elem = deserializer.deserialize(serUnit.data["elem"])
return IList(items, elem=elem)
2 changes: 2 additions & 0 deletions src/kirin/interp/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,10 @@ def frame_call_region(
InterpreterError: if cannot find a matching implementation for the region.
"""
region_trait = node.get_present_trait(ir.RegionInterpretationTrait)

how = self.registry.get(Signature(region_trait))
if how is None:

raise InterpreterError(
f"Interpreter {self.__class__.__name__} does not "
f"support {node} using {region_trait} convention"
Expand Down
28 changes: 25 additions & 3 deletions src/kirin/ir/attrs/py.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@

from kirin.print import Printer
from kirin.ir.attrs.abc import Attribute
from kirin.serialization.core.serializable import Serializable
from kirin.serialization.core.supportedtypes import SUPPORTED_PYTHON_TYPES
from kirin.serialization.core.serializationunit import SerializationUnit

if TYPE_CHECKING:
from kirin.serialization.base.serializationunit import SerializationUnit
from kirin.serialization.base.serializer import Serializer
from kirin.serialization.base.deserializer import Deserializer

Expand Down Expand Up @@ -70,17 +72,37 @@ def is_structurally_equal(
if isinstance(self.data, StructurallyEqual) and isinstance(
other.data, StructurallyEqual
):

return self.data.is_structurally_equal(other.data, context=context)
return self.data == other.data

def serialize(self, serializer: "Serializer") -> "SerializationUnit":
return serializer.serialize_pyattr(self)
if not (
isinstance(self.data, SUPPORTED_PYTHON_TYPES)
or isinstance(self.data, Serializable)
):
raise TypeError(
f"Cannot serialize data of type {type(self.data)}. "
"Data must be one of the supported Python types."
)

return SerializationUnit(
kind="pyattr",
module_name=self.__module__,
class_name=self.__class__.__name__,
data={
"data": serializer.serialize(self.data),
"pytype": serializer.serialize_attribute(self.type),
},
)

@classmethod
def deserialize(
cls: Type["PyAttr"], serUnit: "SerializationUnit", deserializer: "Deserializer"
) -> "PyAttr":
return deserializer.deserialize_pyattr(serUnit)
pytype = deserializer.deserialize(serUnit.data["pytype"])
value = deserializer.deserialize(serUnit.data["data"])
return PyAttr(value, pytype=pytype)


@runtime_checkable
Expand Down
114 changes: 97 additions & 17 deletions src/kirin/ir/attrs/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
from beartype.door import TupleVariableTypeHint # type: ignore
from beartype.door import TypeHint, ClassTypeHint, LiteralTypeHint, TypeVarTypeHint

from kirin.serialization.core.serializable import Serializable
from kirin.serialization.core.supportedtypes import SUPPORTED_PYTHON_TYPES
from kirin.serialization.core.serializationunit import SerializationUnit

if TYPE_CHECKING:
from kirin.serialization.base.serializationunit import SerializationUnit
from kirin.serialization.base.serializer import Serializer
from kirin.serialization.base.deserializer import Deserializer

Expand Down Expand Up @@ -111,13 +114,18 @@ def is_structurally_equal(
return isinstance(other, AnyType)

def serialize(self, serializer: "Serializer") -> "SerializationUnit":
return serializer.serialize_anytype(self)
return SerializationUnit(
kind="type-attribute",
module_name=self.__module__,
class_name=self.__class__.__name__,
data=dict(),
)

@classmethod
def deserialize(
cls, serUnit: "SerializationUnit", deserializer: "Deserializer"
) -> "AnyType":
return deserializer.deserialize_anytype(serUnit)
return AnyType()


@typing.final
Expand All @@ -139,13 +147,18 @@ def is_structurally_equal(
return isinstance(other, BottomType)

def serialize(self, serializer: "Serializer") -> "SerializationUnit":
return serializer.serialize_bottomtype(self)
return SerializationUnit(
kind="type-attribute",
module_name=self.__module__,
class_name=self.__class__.__name__,
data=dict(),
)

@classmethod
def deserialize(
cls, serUnit: "SerializationUnit", deserializer: "Deserializer"
) -> "BottomType":
return deserializer.deserialize_bottomtype(serUnit)
return BottomType()


class PyClassMeta(TypeAttributeMeta):
Expand Down Expand Up @@ -239,13 +252,26 @@ def is_structurally_equal(
return isinstance(other, PyClass) and self.typ == other.typ

def serialize(self, serializer: "Serializer") -> "SerializationUnit":
return serializer.serialize_pyclass(self)
return SerializationUnit(
kind="type-attribute",
module_name=self.__module__,
class_name=self.__class__.__name__,
data=dict(
typ=serializer.serialize_type(self.typ),
display_name=serializer.serialize_str(self.display_name),
prefix=serializer.serialize_str(self.prefix),
),
)

@classmethod
def deserialize(
cls, serUnit: "SerializationUnit", deserializer: "Deserializer"
) -> "PyClass":
return deserializer.deserialize_pyclass(serUnit)
return PyClass(
typ=deserializer.deserialize(serUnit.data["typ"]),
display_name=deserializer.deserialize(serUnit.data.get("display_name", "")),
prefix=deserializer.deserialize(serUnit.data.get("prefix", "")),
)


class LiteralMeta(TypeAttributeMeta):
Expand Down Expand Up @@ -318,13 +344,31 @@ def is_structurally_equal(
)

def serialize(self, serializer: "Serializer") -> "SerializationUnit":
return serializer.serialize_literal(self)
if not (
isinstance(self.data, SUPPORTED_PYTHON_TYPES)
or isinstance(self.data, Serializable)
):
raise ValueError(
f"Unsupported data type {type(self.data)} for serialization. Implement 'serialize' method."
)
else:
return SerializationUnit(
kind="type-attribute",
module_name=self.__module__,
class_name=self.__class__.__name__,
data={
"value": serializer.serialize(self.data),
"type": serializer.serialize_attribute(self.type),
},
)

@classmethod
def deserialize(
cls, serUnit: "SerializationUnit", deserializer: "Deserializer"
) -> "Literal":
return deserializer.deserialize_literal(serUnit)
d = deserializer.deserialize(serUnit.data["value"])
type_attr = deserializer.deserialize(serUnit.data["type"])
return Literal(d, type_attr)


@typing.final
Expand Down Expand Up @@ -390,13 +434,19 @@ def is_structurally_equal(
return isinstance(other, Union) and self.types == other.types

def serialize(self, serializer: "Serializer") -> "SerializationUnit":
return serializer.serialize_union(self)
return SerializationUnit(
kind="type-attribute",
module_name=self.__module__,
class_name=self.__class__.__name__,
data={"types": serializer.serialize_frozenset(self.types)},
)

@classmethod
def deserialize(
cls, serUnit: "SerializationUnit", deserializer: "Deserializer"
) -> "Union":
return deserializer.deserialize_union(serUnit)
ty = deserializer.deserialize_frozenset(serUnit.data["types"])
return Union(ty)


@typing.final
Expand Down Expand Up @@ -438,13 +488,23 @@ def is_structurally_equal(
)

def serialize(self, serializer: "Serializer") -> "SerializationUnit":
return serializer.serialize_typevar(self)
return SerializationUnit(
kind="type-attribute",
module_name=self.__module__,
class_name=self.__class__.__name__,
data={
"varname": serializer.serialize_str(self.varname),
"bound": serializer.serialize_attribute(self.bound),
},
)

@classmethod
def deserialize(
cls, serUnit: "SerializationUnit", deserializer: "Deserializer"
) -> "TypeVar":
return deserializer.deserialize_typevar(serUnit)
varname = deserializer.deserialize(serUnit.data["varname"])
bound = deserializer.deserialize(serUnit.data["bound"])
return TypeVar(varname, bound)


@typing.final
Expand Down Expand Up @@ -472,13 +532,19 @@ def is_structurally_equal(
return isinstance(other, Vararg) and self.typ.is_structurally_equal(other.typ)

def serialize(self, serializer: "Serializer") -> "SerializationUnit":
return serializer.serialize_vararg(self)
return SerializationUnit(
kind="type-attribute",
module_name=self.__module__,
class_name=self.__class__.__name__,
data={"typ": serializer.serialize_attribute(self.typ)},
)

@classmethod
def deserialize(
cls, serUnit: "SerializationUnit", deserializer: "Deserializer"
) -> "Vararg":
return deserializer.deserialize_vararg(serUnit)
typ = deserializer.deserialize(serUnit.data["typ"])
return Vararg(typ)


TypeVarValue: typing.TypeAlias = TypeAttribute | Vararg | list
Expand Down Expand Up @@ -627,13 +693,27 @@ def is_structurally_equal(
return False

def serialize(self, serializer: "Serializer") -> "SerializationUnit":
return serializer.serialize_generic(self)
return SerializationUnit(
kind="type-attribute",
module_name=self.__module__,
class_name=self.__class__.__name__,
data={
"body": serializer.serialize(self.body),
"vars": serializer.serialize_tuple(self.vars),
"vararg": serializer.serialize(self.vararg),
},
)

@classmethod
def deserialize(
cls, serUnit: "SerializationUnit", deserializer: "Deserializer"
) -> "Generic":
return deserializer.deserialize_generic(serUnit)
body = deserializer.deserialize(serUnit.data["body"])
vars = deserializer.deserialize_tuple(serUnit.data["vars"])
vararg = deserializer.deserialize(serUnit.data["vararg"])
out = Generic(body, *vars)
out.vararg = vararg
return out


def _typeparams_list2tuple(args: tuple[TypeVarValue, ...]) -> tuple[TypeOrVararg, ...]:
Expand Down
2 changes: 1 addition & 1 deletion src/kirin/ir/dialect.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from kirin.lowering.python.dialect import FromPythonAST
from kirin.serialization.base.serializer import Serializer
from kirin.serialization.base.deserializer import Deserializer
from kirin.serialization.base.serializationunit import SerializationUnit
from kirin.serialization.core.serializationunit import SerializationUnit


@dataclass
Expand Down
Loading
Loading