Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 6 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "guppy-gpu"
version = "0.1.1"
version = "0.1.2"
description = "Guppy library for real-time GPU decoding on Quantinuum hardware."
readme = "README.md"
license = { file = "LICENSE" }
Expand All @@ -13,17 +13,17 @@ maintainers = [
]
requires-python = ">=3.10"
dependencies = [
"guppylang-internals>=0.25.0",
"guppylang>=0.21.4",
"hugr~=0.15.0",
"tket-exts>=0.11.0",
"guppylang-internals>=0.24.0,<1.0.0a0",
"guppylang>=0.21.4,<1.0.0a0",
"hugr>=0.13.1,<0.17",
Comment thread
qartik marked this conversation as resolved.
"tket-exts>=0.11.0,<0.13",
]

[dependency-groups]
dev = ["pytest>=8.4.2"]

[build-system]
requires = ["uv_build>=0.9.7,<0.10.0"]
requires = ["uv_build>=0.9.7,<0.11.0"]
build-backend = "uv_build"

[tool.deptry]
Expand Down
44 changes: 39 additions & 5 deletions src/guppy_gpu/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,40 @@
P = ParamSpec("P")


def register_type_member(ty_id: DefId, name: str, member_id: DefId) -> None:
register = getattr(DEF_STORE, "register_type_member", None)
if register is None:
register = DEF_STORE.register_impl
register(ty_id, name, member_id)


def custom_function_def(
id: DefId,
name: str,
defined_at: ast.AST | None,
ty: FunctionType,
call_checker: DefaultCallChecker,
call_compiler: CustomInoutCallCompiler,
higher_order_value: bool,
higher_order_func_id: GlobalConstId,
has_signature: bool,
) -> CustomFunctionDef:
kwargs = {
"id": id,
"name": name,
"defined_at": defined_at,
"ty": ty,
"call_checker": call_checker,
"call_compiler": call_compiler,
"higher_order_value": higher_order_value,
"higher_order_func_id": higher_order_func_id,
"has_signature": has_signature,
"has_var_args": False,
}
params = inspect.signature(CustomFunctionDef).parameters
return CustomFunctionDef(**{key: value for key, value in kwargs.items() if key in params})
Comment thread
qartik marked this conversation as resolved.


def get_calling_frame() -> FrameType:
"""Finds the first frame that called this function outside the compiler modules."""
frame = inspect.currentframe()
Expand Down Expand Up @@ -105,7 +139,7 @@ def dec(cls: builtins.type[T]) -> GuppyDefinition:
DEF_STORE.register_def(ext_module, get_calling_frame())
for val in cls.__dict__.values():
if isinstance(val, GuppyDefinition):
DEF_STORE.register_impl(ext_module.id, val.wrapped.name, val.id)
register_type_member(ext_module.id, val.wrapped.name, val.id)
# Add a constructor to the class
if init_arg:
init_fn_ty = FunctionType(
Expand All @@ -120,7 +154,7 @@ def dec(cls: builtins.type[T]) -> GuppyDefinition:
else:
init_fn_ty = FunctionType([], ext_module_ty)

call_method = CustomFunctionDef(
call_method = custom_function_def(
DefId.fresh(),
"__new__",
None,
Expand All @@ -131,7 +165,7 @@ def dec(cls: builtins.type[T]) -> GuppyDefinition:
GlobalConstId.fresh(f"{cls.__name__}.__new__"),
True,
)
discard = CustomFunctionDef(
discard = custom_function_def(
DefId.fresh(),
"discard",
None,
Expand All @@ -143,9 +177,9 @@ def dec(cls: builtins.type[T]) -> GuppyDefinition:
True,
)
DEF_STORE.register_def(call_method, get_calling_frame())
DEF_STORE.register_impl(ext_module.id, "__new__", call_method.id)
register_type_member(ext_module.id, "__new__", call_method.id)
DEF_STORE.register_def(discard, get_calling_frame())
DEF_STORE.register_impl(ext_module.id, "discard", discard.id)
register_type_member(ext_module.id, "discard", discard.id)

return GuppyDefinition(ext_module)

Expand Down
143 changes: 143 additions & 0 deletions tests/test_decorator_compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
from guppy_gpu import decorator


def test_register_type_member_uses_new_api(monkeypatch):
calls = []

class DefStore:
def register_type_member(self, *args):
calls.append(("register_type_member", args))

def register_impl(self, *args):
calls.append(("register_impl", args))

monkeypatch.setattr(decorator, "DEF_STORE", DefStore())

decorator.register_type_member("type-id", "member", "member-id")

assert calls == [("register_type_member", ("type-id", "member", "member-id"))]


def test_register_type_member_falls_back_to_register_impl(monkeypatch):
calls = []

class DefStore:
def register_impl(self, *args):
calls.append(("register_impl", args))

monkeypatch.setattr(decorator, "DEF_STORE", DefStore())

decorator.register_type_member("type-id", "member", "member-id")

assert calls == [("register_impl", ("type-id", "member", "member-id"))]


def test_custom_function_def_filters_kwargs_for_old_signature(monkeypatch):
class CustomFunctionDef:
def __init__(
self,
*,
id,
name,
defined_at,
ty,
call_checker,
call_compiler,
higher_order_value,
higher_order_func_id,
has_signature,
):
self.kwargs = {
"id": id,
"name": name,
"defined_at": defined_at,
"ty": ty,
"call_checker": call_checker,
"call_compiler": call_compiler,
"higher_order_value": higher_order_value,
"higher_order_func_id": higher_order_func_id,
"has_signature": has_signature,
}

monkeypatch.setattr(decorator, "CustomFunctionDef", CustomFunctionDef)

result = decorator.custom_function_def(
"id",
"name",
"defined_at",
"ty",
"call_checker",
"call_compiler",
True,
"higher_order_func_id",
True,
)

assert result.kwargs == {
"id": "id",
"name": "name",
"defined_at": "defined_at",
"ty": "ty",
"call_checker": "call_checker",
"call_compiler": "call_compiler",
"higher_order_value": True,
"higher_order_func_id": "higher_order_func_id",
"has_signature": True,
}


def test_custom_function_def_includes_has_var_args_when_supported(monkeypatch):
class CustomFunctionDef:
def __init__(
self,
*,
id,
name,
defined_at,
ty,
call_checker,
call_compiler,
higher_order_value,
higher_order_func_id,
has_var_args,
has_signature,
):
self.kwargs = {
"id": id,
"name": name,
"defined_at": defined_at,
"ty": ty,
"call_checker": call_checker,
"call_compiler": call_compiler,
"higher_order_value": higher_order_value,
"higher_order_func_id": higher_order_func_id,
"has_var_args": has_var_args,
"has_signature": has_signature,
}

monkeypatch.setattr(decorator, "CustomFunctionDef", CustomFunctionDef)

result = decorator.custom_function_def(
"id",
"name",
"defined_at",
"ty",
"call_checker",
"call_compiler",
True,
"higher_order_func_id",
True,
)

assert result.kwargs == {
"id": "id",
"name": "name",
"defined_at": "defined_at",
"ty": "ty",
"call_checker": "call_checker",
"call_compiler": "call_compiler",
"higher_order_value": True,
"higher_order_func_id": "higher_order_func_id",
"has_var_args": False,
"has_signature": True,
}
Loading