From c679c942c84d5c5383db222e08d9d035caf6eeef Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 29 Oct 2024 14:17:46 -0400 Subject: [PATCH 1/9] Add function pretty tests --- python/tests/test_pretty.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/python/tests/test_pretty.py b/python/tests/test_pretty.py index b6217ea4..96fdf4ba 100644 --- a/python/tests/test_pretty.py +++ b/python/tests/test_pretty.py @@ -2,6 +2,7 @@ from __future__ import annotations from copy import copy +from functools import partial from typing import TYPE_CHECKING, ClassVar import pytest @@ -9,6 +10,8 @@ from egglog import * if TYPE_CHECKING: + from collections.abc import Callable + from egglog.runtime import RuntimeExpr @@ -49,6 +52,14 @@ def p() -> i64: ... def has_default(x: A = A()) -> A: ... +@function +def higher_order(x: Callable[[A], A]) -> A: ... + + +@function +def binary(x: A, y: A) -> A: ... + + del_a = A() del del_a[g()] @@ -141,6 +152,11 @@ def my_very_long_function_name() -> A: ... # Functions pytest.param(f, "f", id="function"), pytest.param(A().method, "A().method", id="method"), + # lambda + pytest.param(higher_order(lambda x: A() + x), "higher_order(lambda x: A() + x)", id="lambda"), + # partial + pytest.param(higher_order(partial(binary, A())), "higher_order(partial(binary, A()))", id="partial"), + pytest.param(higher_order(lambda x: f(b)), "higher_order(lambda x: f(b))", id="partial-lambda"), ] From f2796bae92aef09677a964a8fe0cf873e0117183 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 29 Oct 2024 14:18:22 -0400 Subject: [PATCH 2/9] Fix prettifying some functions --- docs/changelog.md | 2 ++ python/egglog/pretty.py | 24 +++++++++--------------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index caac3404..1c36a771 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -4,6 +4,8 @@ _This project uses semantic versioning_ ## UNRELEASED +- Fix pretty printing of lambda functions + ## 8.0.1 (2024-10-24) - Upgrade dependencies including [egglog](https://github.com/egraphs-good/egglog/compare/saulshanabrook:egg-smol:a555b2f5e82c684442775cc1a5da94b71930113c...b0db06832264c9b22694bd3de2bdacd55bbe9e32) diff --git a/python/egglog/pretty.py b/python/egglog/pretty.py index 6b6db444..4e44e348 100644 --- a/python/egglog/pretty.py +++ b/python/egglog/pretty.py @@ -115,11 +115,7 @@ def pretty_callable_ref( # Either returns a function or a function with args. If args are provided, they would just be called, # on the function, so return them, because they are dummies if isinstance(res, tuple): - name = res[0] - # if this is an unnamed function, return it but don't partially apply any args - if isinstance(name, UnnamedFunctionRef): - return context._pretty_function_body(name, []) - return name + return res[0] return res @@ -256,7 +252,7 @@ def uncached(self, decl: AllDecls, *, unwrap_lit: bool, parens: bool, ruleset_na case CallDecl(_, _, _): return self._call(decl, parens) case PartialCallDecl(CallDecl(ref, typed_args, _)): - return self._pretty_partial(ref, [a.expr for a in typed_args]), "fn" + return self._pretty_partial(ref, [a.expr for a in typed_args], parens), "fn" case PyObjectDecl(value): return repr(value) if unwrap_lit else f"PyObject({value!r})", "PyObject" case ActionCommandDecl(action): @@ -368,11 +364,7 @@ def _call( expr_name = None res = self._call_inner(ref, args, decl.bound_tp_params, parens) expr = ( - ( - f"{name}({', '.join(self(a, parens=False, unwrap_lit=True) for a in res[1])})" - if isinstance((name := res[0]), str) - else ((called := self._pretty_function_body(name, res[1])) if not parens else f"({called})") - ) + (f"{res[0]}({', '.join(self(a, parens=False, unwrap_lit=True) for a in res[1])})") if isinstance(res, tuple) else res ) @@ -388,7 +380,7 @@ def _call_inner( # noqa: C901, PLR0911, PLR0912 args: list[ExprDecl], bound_tp_params: tuple[JustTypeRef, ...] | None, parens: bool, - ) -> tuple[str | UnnamedFunctionRef, list[ExprDecl]] | str: + ) -> tuple[str, list[ExprDecl]] | str: """ Pretty print the call, returning either the full function call or a tuple of the function and the args. """ @@ -428,7 +420,8 @@ def _call_inner( # noqa: C901, PLR0911, PLR0912 tp_ref = JustTypeRef(class_name, bound_tp_params or ()) return str(tp_ref), args case UnnamedFunctionRef(): - return ref, args + expr = self._pretty_function_body(ref, []) + return f"({expr})", args assert_never(ref) def _generate_name(self, typ: str) -> str: @@ -449,7 +442,7 @@ def _name_expr(self, tp_name: str, expr_str: str, copy_identifier: bool) -> str: self.statements.append(f"{name} = {expr_str}") return name - def _pretty_partial(self, ref: CallableRef, args: list[ExprDecl]) -> str: + def _pretty_partial(self, ref: CallableRef, args: list[ExprDecl], parens: bool) -> str: """ Returns a partial function call as a string. """ @@ -457,7 +450,8 @@ def _pretty_partial(self, ref: CallableRef, args: list[ExprDecl]) -> str: case FunctionRef(name): fn = name case UnnamedFunctionRef(): - return self._pretty_function_body(ref, args) + res = self._pretty_function_body(ref, args) + return f"({res})" if parens else res case ( ClassMethodRef(class_name, method_name) | MethodRef(class_name, method_name) From abe1c973a8ed01ba6d5985d098a539b700dc5ef7 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 29 Oct 2024 14:19:08 -0400 Subject: [PATCH 3/9] Add jupyterlab as dev dep --- pyproject.toml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 69955f70..f3670e8c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,14 @@ array = [ "numba==0.59.1", "llvmlite==0.42.0", ] -dev = ["ruff", "pre-commit", "mypy", "anywidget[dev]", "egglog[docs,test]"] +dev = [ + "ruff", + "pre-commit", + "mypy", + "anywidget[dev]", + "egglog[docs,test]", + "jupyterlab", +] test = [ "pytest", From e9da7697193159239af33253c2fdcb8c2db55ca2 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 29 Oct 2024 14:19:26 -0400 Subject: [PATCH 4/9] Fix instructions on how to recompile code --- docs/reference/contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/contributing.md b/docs/reference/contributing.md index 2848053b..e8b61bc9 100644 --- a/docs/reference/contributing.md +++ b/docs/reference/contributing.md @@ -33,7 +33,7 @@ Then install the package in editable mode with the development dependencies: uv sync --all-extras ``` -Anytime you change the rust code, you can run `uv sync` to recompile the rust code. +Anytime you change the rust code, you can run `uv sync --reinstall-package egglog --all-extras` to force recompiling the rust code. If you would like to download a new version of the visualizer source, run `make clean; make`. This will download the most recent released version from the github actions artifact in the [egraph-visualizer](https://github.com/egraphs-good/egraph-visualizer) repo. It is checked in because it's a pain to get cargo to include only one git ignored file while ignoring the rest of the files that were ignored. From 7a8a8bcd90b62fc2802c850ba7a3a7a6b92178b4 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 29 Oct 2024 14:21:12 -0400 Subject: [PATCH 5/9] Catch panics when trying to eval --- python/egglog/exp/array_api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/egglog/exp/array_api.py b/python/egglog/exp/array_api.py index d494746b..42573f16 100644 --- a/python/egglog/exp/array_api.py +++ b/python/egglog/exp/array_api.py @@ -14,7 +14,6 @@ import numpy as np from egglog import * -from egglog.bindings import EggSmolError from egglog.runtime import RuntimeExpr from .program_gen import * @@ -1539,13 +1538,14 @@ def try_evaling(expr: Expr, prim_expr: i64 | Bool) -> int | bool: egraph.run(array_api_schedule) try: extracted = egraph.extract(prim_expr) - except EggSmolError as exc: + # Catch base exceptions so that we catch rust panics which happen when trying to extract subsumed nodes + except BaseException as exc: + egraph.display(n_inline_leaves=1, split_primitive_outputs=True) # Try giving some context, by showing the smallest version of the larger expression try: expr_extracted = egraph.extract(expr) - except EggSmolError as inner_exc: + except BaseException as inner_exc: raise ValueError(f"Cannot simplify {expr}") from inner_exc - egraph.display(n_inline_leaves=1, split_primitive_outputs=True) msg = f"Cannot simplify to primitive {expr_extracted}" raise ValueError(msg) from exc return egraph.eval(extracted) From 9757726e1919ef2494bcecfb33c1e0861f4286cd Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 29 Oct 2024 14:22:59 -0400 Subject: [PATCH 6/9] Support subsumption in defaults --- docs/changelog.md | 1 + python/egglog/declarations.py | 1 + python/egglog/egraph.py | 76 +++++++++++++++++++------ python/egglog/egraph_state.py | 4 +- python/egglog/exp/array_api.py | 13 +++-- python/egglog/exp/array_api_loopnest.py | 28 ++++----- python/egglog/exp/array_api_numba.py | 2 +- 7 files changed, 87 insertions(+), 38 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 1c36a771..2d1ccf1b 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -5,6 +5,7 @@ _This project uses semantic versioning_ ## UNRELEASED - Fix pretty printing of lambda functions +- Add support for subsuming rewrite generated by default function and method definitions ## 8.0.1 (2024-10-24) diff --git a/python/egglog/declarations.py b/python/egglog/declarations.py index e060f9a1..86ad479f 100644 --- a/python/egglog/declarations.py +++ b/python/egglog/declarations.py @@ -764,6 +764,7 @@ class RuleDecl: class DefaultRewriteDecl: ref: CallableRef expr: ExprDecl + subsume: bool RewriteOrRuleDecl: TypeAlias = RewriteDecl | BiRewriteDecl | RuleDecl | DefaultRewriteDecl diff --git a/python/egglog/egraph.py b/python/egglog/egraph.py index 097835c8..75d21ec4 100644 --- a/python/egglog/egraph.py +++ b/python/egglog/egraph.py @@ -269,7 +269,7 @@ def method( unextractable: bool = False, ) -> Callable[[Callable[P, EXPR]], Callable[P, EXPR]]: return lambda fn: _WrappedMethod( - egg_fn, cost, default, merge, on_merge, fn, preserve, mutates_self, unextractable + egg_fn, cost, default, merge, on_merge, fn, preserve, mutates_self, unextractable, False ) @overload @@ -404,6 +404,7 @@ def method( on_merge: Callable[[Any, Any], Iterable[ActionLike]] | None = None, mutates_self: bool = False, unextractable: bool = False, + subsume: bool = False, ) -> Callable[[CALLABLE], CALLABLE]: ... @@ -417,6 +418,7 @@ def method( on_merge: Callable[[EXPR, EXPR], Iterable[ActionLike]] | None = None, mutates_self: bool = False, unextractable: bool = False, + subsume: bool = False, ) -> Callable[[Callable[P, EXPR]], Callable[P, EXPR]]: ... @@ -430,11 +432,14 @@ def method( preserve: bool = False, mutates_self: bool = False, unextractable: bool = False, + subsume: bool = False, ) -> Callable[[Callable[P, EXPR]], Callable[P, EXPR]]: """ Any method can be decorated with this to customize it's behavior. This is only supported in classes which subclass :class:`Expr`. """ - return lambda fn: _WrappedMethod(egg_fn, cost, default, merge, on_merge, fn, preserve, mutates_self, unextractable) + return lambda fn: _WrappedMethod( + egg_fn, cost, default, merge, on_merge, fn, preserve, mutates_self, unextractable, subsume + ) class _ExprMetaclass(type): @@ -519,7 +524,9 @@ def _generate_class_decls( # noqa: C901,PLR0912 (inner_tp,) = v.__args__ type_ref = resolve_type_annotation(decls, inner_tp) cls_decl.class_variables[k] = ConstantDecl(type_ref.to_just()) - _add_default_rewrite(decls, ClassVariableRef(cls_name, k), type_ref, namespace.pop(k, None), ruleset) + _add_default_rewrite( + decls, ClassVariableRef(cls_name, k), type_ref, namespace.pop(k, None), ruleset, subsume=False + ) else: msg = f"On class {cls_name}, for attribute '{k}', expected a ClassVar, but got {v}" raise NotImplementedError(msg) @@ -542,12 +549,12 @@ def _generate_class_decls( # noqa: C901,PLR0912 if is_init and cls_name in LIT_CLASS_NAMES: continue match method: - case _WrappedMethod(egg_fn, cost, default, merge, on_merge, fn, preserve, mutates, unextractable): + case _WrappedMethod(egg_fn, cost, default, merge, on_merge, fn, preserve, mutates, unextractable, subsume): pass case _: egg_fn, cost, default, merge, on_merge = None, None, None, None, None fn = method - unextractable, preserve = False, False + unextractable, preserve, subsume = False, False, False mutates = method_name in ALWAYS_MUTATES_SELF if preserve: cls_decl.preserved_methods[method_name] = fn @@ -572,7 +579,20 @@ def _generate_class_decls( # noqa: C901,PLR0912 continue _, add_rewrite = _fn_decl( - decls, egg_fn, ref, fn, locals, default, cost, merge, on_merge, mutates, builtin, ruleset, unextractable + decls, + egg_fn, + ref, + fn, + locals, + default, + cost, + merge, + on_merge, + mutates, + builtin, + ruleset=ruleset, + unextractable=unextractable, + subsume=subsume, ) if not builtin and not isinstance(ref, InitRef) and not mutates: @@ -602,6 +622,7 @@ def function( builtin: bool = False, ruleset: Ruleset | None = None, use_body_as_name: bool = False, + subsume: bool = False, ) -> Callable[[CALLABLE], CALLABLE]: ... @@ -617,6 +638,7 @@ def function( unextractable: bool = False, ruleset: Ruleset | None = None, use_body_as_name: bool = False, + subsume: bool = False, ) -> Callable[[Callable[P, EXPR]], Callable[P, EXPR]]: ... @@ -649,6 +671,7 @@ class _FunctionConstructor: unextractable: bool = False ruleset: Ruleset | None = None use_body_as_name: bool = False + subsume: bool = False def __call__(self, fn: Callable[..., RuntimeExpr]) -> RuntimeFunction: return RuntimeFunction(*split_thunk(Thunk.fn(self.create_decls, fn))) @@ -668,7 +691,8 @@ def create_decls(self, fn: Callable[..., RuntimeExpr]) -> tuple[Declarations, Ca self.on_merge, self.mutates_first_arg, self.builtin, - self.ruleset, + ruleset=self.ruleset, + subsume=self.subsume, unextractable=self.unextractable, ) add_rewrite() @@ -690,6 +714,7 @@ def _fn_decl( on_merge: Callable[[RuntimeExpr, RuntimeExpr], Iterable[ActionLike]] | None, mutates_first_arg: bool, is_builtin: bool, + subsume: bool, ruleset: Ruleset | None = None, unextractable: bool = False, ) -> tuple[CallableRef, Callable[[], None]]: @@ -804,7 +829,7 @@ def _fn_decl( res_ref = ref decls.set_function_decl(ref, decl) res_thunk = Thunk.fn(_create_default_value, decls, ref, fn, args, ruleset) - return res_ref, Thunk.fn(_add_default_rewrite_function, decls, res_ref, return_type, ruleset, res_thunk) + return res_ref, Thunk.fn(_add_default_rewrite_function, decls, res_ref, return_type, ruleset, res_thunk, subsume) # Overload to support aritys 0-4 until variadic generic support map, so we can map from type to value @@ -871,7 +896,7 @@ def _constant_thunk( type_ref = resolve_type_annotation(decls, tp) callable_ref = ConstantRef(name) decls._constants[name] = ConstantDecl(type_ref.to_just(), egg_name) - _add_default_rewrite(decls, callable_ref, type_ref, default_replacement, ruleset) + _add_default_rewrite(decls, callable_ref, type_ref, default_replacement, ruleset, subsume=False) return decls, TypedExprDecl(type_ref.to_just(), CallDecl(callable_ref)) @@ -898,15 +923,21 @@ def _add_default_rewrite_function( res_type: TypeOrVarRef, ruleset: Ruleset | None, value_thunk: Callable[[], object], + subsume: bool, ) -> None: """ Helper functions that resolves a value thunk to create the default value. """ - _add_default_rewrite(decls, ref, res_type, value_thunk(), ruleset) + _add_default_rewrite(decls, ref, res_type, value_thunk(), ruleset, subsume) def _add_default_rewrite( - decls: Declarations, ref: CallableRef, type_ref: TypeOrVarRef, default_rewrite: object, ruleset: Ruleset | None + decls: Declarations, + ref: CallableRef, + type_ref: TypeOrVarRef, + default_rewrite: object, + ruleset: Ruleset | None, + subsume: bool, ) -> None: """ Adds a default rewrite for the callable, if the default rewrite is not None @@ -916,7 +947,7 @@ def _add_default_rewrite( if default_rewrite is None: return resolved_value = resolve_literal(type_ref, default_rewrite, Thunk.value(decls)) - rewrite_decl = DefaultRewriteDecl(ref, resolved_value.__egg_typed_expr__.expr) + rewrite_decl = DefaultRewriteDecl(ref, resolved_value.__egg_typed_expr__.expr, subsume) if ruleset: ruleset_decls = ruleset._current_egg_decls ruleset_decl = ruleset.__egg_ruleset__ @@ -1338,11 +1369,22 @@ def saturate( Saturate the egraph, running the given schedule until the egraph is saturated. It serializes the egraph at each step and returns a widget to visualize the egraph. """ - from .visualizer_widget import VisualizerWidget + # from .visualizer_widget import VisualizerWidget + + last_expr = None + index = 0 + exprs = [] def to_json() -> str: - if expr: - print(self.extract(expr)) + nonlocal last_expr, index + if expr is not None: + extracted = self.extract(expr) + # s = str(extracted) + if extracted.__egg_typed_expr__ != last_expr: + exprs.append(extracted) + last_expr = extracted.__egg_typed_expr__ + print(f"# {index}:\n", str(extracted), "\n") + index += 1 return self._serialize(**kwargs).to_json() egraphs = [to_json()] @@ -1350,7 +1392,8 @@ def to_json() -> str: while self.run(schedule or 1).updated and i < max: i += 1 egraphs.append(to_json()) - VisualizerWidget(egraphs=egraphs).display_or_open() + # VisualizerWidget(egraphs=egraphs).display_or_open() + return exprs @classmethod def current(cls) -> EGraph: @@ -1407,6 +1450,7 @@ class _WrappedMethod(Generic[P, EXPR]): preserve: bool mutates_self: bool unextractable: bool + subsume: bool def __call__(self, *args: P.args, **kwargs: P.kwargs) -> EXPR: msg = "We should never call a wrapped method. Did you forget to wrap the class?" diff --git a/python/egglog/egraph_state.py b/python/egglog/egraph_state.py index bb814af1..2c3adfef 100644 --- a/python/egglog/egraph_state.py +++ b/python/egglog/egraph_state.py @@ -134,7 +134,7 @@ def command_to_egg(self, cmd: CommandDecl, ruleset: str) -> bindings._Command: ) return bindings.RuleCommand(name or "", ruleset, rule) # TODO: Replace with just constants value and looking at REF of function - case DefaultRewriteDecl(ref, expr): + case DefaultRewriteDecl(ref, expr, subsume): decl = self.__egg_decls__.get_callable_decl(ref).to_function_decl() sig = decl.signature assert isinstance(sig, FunctionSignature) @@ -144,7 +144,7 @@ def command_to_egg(self, cmd: CommandDecl, ruleset: str) -> bindings._Command: for name, tp in zip(sig.arg_names, sig.arg_types, strict=False) ) rewrite_decl = RewriteDecl( - sig.semantic_return_type.to_just(), CallDecl(ref, arg_mapping), expr, (), False + sig.semantic_return_type.to_just(), CallDecl(ref, arg_mapping), expr, (), subsume ) return self.command_to_egg(rewrite_decl, ruleset) case _: diff --git a/python/egglog/exp/array_api.py b/python/egglog/exp/array_api.py index 42573f16..47b9ecc7 100644 --- a/python/egglog/exp/array_api.py +++ b/python/egglog/exp/array_api.py @@ -271,7 +271,6 @@ def var(cls, name: StringLike) -> TupleInt: ... EMPTY: ClassVar[TupleInt] - @method(unextractable=True) def __init__(self, length: IntLike, idx_fn: Callable[[Int], Int]) -> None: ... @classmethod @@ -286,6 +285,7 @@ def range(cls, stop: Int) -> TupleInt: def from_vec(cls, vec: Vec[Int]) -> TupleInt: return TupleInt(vec.length(), partial(index_vec_int, vec)) + @method(subsume=True) def __add__(self, other: TupleInt) -> TupleInt: return TupleInt( self.length() + other.length(), @@ -307,13 +307,13 @@ def fold(self, init: Int, f: Callable[[Int, Int], Int]) -> Int: ... def fold_boolean(self, init: Boolean, f: Callable[[Boolean, Int], Boolean]) -> Boolean: ... + @method(subsume=True) def contains(self, i: Int) -> Boolean: return self.fold_boolean(FALSE, lambda acc, j: acc | (i == j)) - @method(cost=100) def filter(self, f: Callable[[Int], Boolean]) -> TupleInt: ... - @method(cost=100) + @method(subsume=True) def map(self, f: Callable[[Int], Int]) -> TupleInt: return TupleInt(self.length(), lambda i: f(self[i])) @@ -371,7 +371,7 @@ def _tuple_int( ne(k).to(i64(0)), ), # Empty - rewrite(TupleInt.EMPTY).to(TupleInt(0, bottom_indexing)), + rewrite(TupleInt.EMPTY, subsume=True).to(TupleInt(0, bottom_indexing)), # if_ rewrite(TupleInt.if_(TRUE, ti, ti2)).to(ti), rewrite(TupleInt.if_(FALSE, ti, ti2)).to(ti2), @@ -387,13 +387,16 @@ def var(cls, name: StringLike) -> TupleTupleInt: ... def __init__(self, length: IntLike, idx_fn: Callable[[Int], TupleInt]) -> None: ... @classmethod + @method(subsume=True) def single(cls, i: TupleInt) -> TupleTupleInt: return TupleTupleInt(Int(1), lambda _: i) @classmethod + @method(subsume=True) def from_vec(cls, vec: Vec[Int]) -> TupleInt: return TupleInt(vec.length(), partial(index_vec_int, vec)) + @method(subsume=True) def __add__(self, other: TupleTupleInt) -> TupleTupleInt: return TupleTupleInt( self.length() + other.length(), @@ -731,7 +734,7 @@ def _tuple_value( rewrite(TupleValue.EMPTY.includes(v)).to(FALSE), rewrite(TupleValue(v).includes(v)).to(TRUE), rewrite(TupleValue(v).includes(v2)).to(FALSE, ne(v).to(v2)), - rewrite((ti + ti2).includes(v)).to(ti.includes(v) | ti2.includes(v)), + rewrite((ti + ti2).includes(v), subsume=True).to(ti.includes(v) | ti2.includes(v)), ] diff --git a/python/egglog/exp/array_api_loopnest.py b/python/egglog/exp/array_api_loopnest.py index a1222eb5..c512b6a2 100644 --- a/python/egglog/exp/array_api_loopnest.py +++ b/python/egglog/exp/array_api_loopnest.py @@ -14,29 +14,25 @@ class ShapeAPI(Expr): - @method(unextractable=True) def __init__(self, dims: TupleIntLike) -> None: ... - @method(unextractable=True) def deselect(self, axis: TupleIntLike) -> ShapeAPI: ... - @method(unextractable=True) def select(self, axis: TupleIntLike) -> ShapeAPI: ... - @method(unextractable=True) def to_tuple(self) -> TupleInt: ... @array_api_ruleset.register def shape_api_ruleset(dims: TupleInt, axis: TupleInt): s = ShapeAPI(dims) - yield rewrite(s.deselect(axis)).to( + yield rewrite(s.deselect(axis), subsume=True).to( ShapeAPI(TupleInt.range(dims.length()).filter(lambda i: ~axis.contains(i)).map(lambda i: dims[i])) ) - yield rewrite(s.select(axis)).to( + yield rewrite(s.select(axis), subsume=True).to( ShapeAPI(TupleInt.range(dims.length()).filter(lambda i: axis.contains(i)).map(lambda i: dims[i])) ) - yield rewrite(s.to_tuple()).to(dims) + yield rewrite(s.to_tuple(), subsume=True).to(dims) class OptionalLoopNestAPI(Expr): @@ -91,23 +87,27 @@ def _loopnest_api_ruleset( i: i64, ): # from_tuple - yield rewrite(LoopNestAPI.from_tuple(TupleInt(0, idx_fn))).to(OptionalLoopNestAPI.NONE) - yield rewrite(LoopNestAPI.from_tuple(TupleInt(Int(i), idx_fn))).to( + yield rewrite(LoopNestAPI.from_tuple(TupleInt(0, idx_fn)), subsume=True).to(OptionalLoopNestAPI.NONE) + yield rewrite(LoopNestAPI.from_tuple(TupleInt(Int(i), idx_fn)), subsume=True).to( OptionalLoopNestAPI( LoopNestAPI(idx_fn(Int(0)), LoopNestAPI.from_tuple(TupleInt(Int(i - 1), lambda i: idx_fn(i + 1)))) ), ne(i).to(i64(0)), ) # reduce - yield rewrite(lna.fold(fn, init)).to(tuple_tuple_int_reduce_ndarray(lna.indices, fn, init)) + yield rewrite(lna.fold(fn, init), subsume=True).to(tuple_tuple_int_reduce_ndarray(lna.indices, fn, init)) # get_dims - yield rewrite(LoopNestAPI(dim, OptionalLoopNestAPI.NONE).get_dims()).to(TupleInt.single(dim)) - yield rewrite(LoopNestAPI(dim, OptionalLoopNestAPI(lna)).get_dims()).to(TupleInt.single(dim) + lna.get_dims()) + yield rewrite(LoopNestAPI(dim, OptionalLoopNestAPI.NONE).get_dims(), subsume=True).to(TupleInt.single(dim)) + yield rewrite(LoopNestAPI(dim, OptionalLoopNestAPI(lna)).get_dims(), subsume=True).to( + TupleInt.single(dim) + lna.get_dims() + ) # indices - yield rewrite(lna.indices).to(tuple_tuple_int_product(tuple_int_map_tuple_int(lna.get_dims(), TupleInt.range))) + yield rewrite(lna.indices, subsume=True).to( + tuple_tuple_int_product(tuple_int_map_tuple_int(lna.get_dims(), TupleInt.range)) + ) -@function(ruleset=array_api_ruleset, unextractable=True) +@function(ruleset=array_api_ruleset, subsume=True) def linalg_norm(X: NDArray, axis: TupleIntLike) -> NDArray: # peel off the outer shape for result array outshape = ShapeAPI(X.shape).deselect(axis).to_tuple() diff --git a/python/egglog/exp/array_api_numba.py b/python/egglog/exp/array_api_numba.py index eb47f6e8..838f78d7 100644 --- a/python/egglog/exp/array_api_numba.py +++ b/python/egglog/exp/array_api_numba.py @@ -40,7 +40,7 @@ def _std(y: NDArray, x: NDArray, i: Int): # rewrite unique_counts to count each value one by one, since numba doesn't support np.unique(..., return_counts=True) -@function(unextractable=True) +@function def count_values(x: NDArray, values: NDArray) -> TupleValue: """ Returns a tuple of the count of each of the values in the array. From f9b45abd9a39305adcd58c6ea70a7d2738c643e2 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 29 Oct 2024 14:23:13 -0400 Subject: [PATCH 7/9] uv lock update for jupyterlab --- uv.lock | 398 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 397 insertions(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index 7c99793c..68b309c4 100644 --- a/uv.lock +++ b/uv.lock @@ -89,6 +89,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321 }, ] +[[package]] +name = "argon2-cffi" +version = "23.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argon2-cffi-bindings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124 }, +] + +[[package]] +name = "argon2-cffi-bindings" +version = "21.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/e9/184b8ccce6683b0aa2fbb7ba5683ea4b9c5763f1356347f1312c32e3c66e/argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", size = 1779911 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/13/838ce2620025e9666aa8f686431f67a29052241692a3dd1ae9d3692a89d3/argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", size = 29658 }, + { url = "https://files.pythonhosted.org/packages/b3/02/f7f7bb6b6af6031edb11037639c697b912e1dea2db94d436e681aea2f495/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", size = 80583 }, + { url = "https://files.pythonhosted.org/packages/ec/f7/378254e6dd7ae6f31fe40c8649eea7d4832a42243acaf0f1fff9083b2bed/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", size = 86168 }, + { url = "https://files.pythonhosted.org/packages/74/f6/4a34a37a98311ed73bb80efe422fed95f2ac25a4cacc5ae1d7ae6a144505/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", size = 82709 }, + { url = "https://files.pythonhosted.org/packages/74/2b/73d767bfdaab25484f7e7901379d5f8793cccbb86c6e0cbc4c1b96f63896/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", size = 83613 }, + { url = "https://files.pythonhosted.org/packages/4f/fd/37f86deef67ff57c76f137a67181949c2d408077e2e3dd70c6c42912c9bf/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", size = 84583 }, + { url = "https://files.pythonhosted.org/packages/6f/52/5a60085a3dae8fded8327a4f564223029f5f54b0cb0455a31131b5363a01/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", size = 88475 }, + { url = "https://files.pythonhosted.org/packages/8b/95/143cd64feb24a15fa4b189a3e1e7efbaeeb00f39a51e99b26fc62fbacabd/argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", size = 27698 }, + { url = "https://files.pythonhosted.org/packages/37/2c/e34e47c7dee97ba6f01a6203e0383e15b60fb85d78ac9a15cd066f6fe28b/argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", size = 30817 }, + { url = "https://files.pythonhosted.org/packages/5a/e4/bf8034d25edaa495da3c8a3405627d2e35758e44ff6eaa7948092646fdcc/argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", size = 53104 }, +] + [[package]] name = "array-api-compat" version = "1.9" @@ -98,6 +131,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/45/78/17985eac75d04c30f8cc375e4400e20b0787dc4a1c853a8fe9fad7932f55/array_api_compat-1.9-py3-none-any.whl", hash = "sha256:76db63c2d2461ba0e86b920c8b087f0a1617eb14de3ec29fe6811eeecad9c5e8", size = 49489 }, ] +[[package]] +name = "arrow" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "types-python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419 }, +] + [[package]] name = "asttokens" version = "2.4.1" @@ -110,6 +156,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/45/86/4736ac618d82a20d87d2f92ae19441ebc7ac9e7a581d7e58bbe79233b24a/asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24", size = 27764 }, ] +[[package]] +name = "async-lru" +version = "2.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/e2/2b4651eff771f6fd900d233e175ddc5e2be502c7eb62c0c42f975c6d36cd/async-lru-2.0.4.tar.gz", hash = "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627", size = 10019 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/9f/3c3503693386c4b0f245eaf5ca6198e3b28879ca0a40bde6b0e319793453/async_lru-2.0.4-py3-none-any.whl", hash = "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224", size = 6111 }, +] + [[package]] name = "attrs" version = "24.2.0" @@ -498,7 +556,7 @@ wheels = [ [[package]] name = "egglog" -version = "8.0.0" +version = "8.0.1" source = { editable = "." } dependencies = [ { name = "anywidget" }, @@ -518,6 +576,7 @@ dev = [ { name = "ablog" }, { name = "anywidget", extra = ["dev"] }, { name = "array-api-compat" }, + { name = "jupyterlab" }, { name = "line-profiler" }, { name = "llvmlite" }, { name = "matplotlib" }, @@ -581,6 +640,7 @@ requires-dist = [ { name = "egglog", extras = ["array"], marker = "extra == 'test'" }, { name = "egglog", extras = ["docs", "test"], marker = "extra == 'dev'" }, { name = "graphviz" }, + { name = "jupyterlab", marker = "extra == 'dev'" }, { name = "line-profiler", marker = "extra == 'docs'" }, { name = "llvmlite", marker = "extra == 'array'", specifier = "==0.42.0" }, { name = "matplotlib", marker = "extra == 'docs'" }, @@ -699,6 +759,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/57/5e/de2e6e51cb6894f2f2bc2641f6c845561361b622e96df3cca04df77222c9/fonttools-4.54.1-py3-none-any.whl", hash = "sha256:37cddd62d83dc4f72f7c3f3c2bcf2697e89a30efb152079896544a93907733bd", size = 1096920 }, ] +[[package]] +name = "fqdn" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121 }, +] + [[package]] name = "graphviz" version = "0.20.3" @@ -759,6 +828,44 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ac/38/08cc303ddddc4b3d7c628c3039a61a3aae36c241ed01393d00c2fd663473/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6", size = 1142112 }, ] +[[package]] +name = "h11" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, +] + +[[package]] +name = "httpcore" +version = "1.0.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b6/44/ed0fa6a17845fb033bd885c03e842f08c1b9406c86a2e60ac1ae1b9206a6/httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f", size = 85180 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/89/b161908e2f51be56568184aeb4a880fd287178d176fd1c860d2217f41106/httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f", size = 78011 }, +] + +[[package]] +name = "httpx" +version = "0.27.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, + { name = "sniffio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/82/08f8c936781f67d9e6b9eeb8a0c8b4e406136ea4c3d1f89a5db71d42e0e6/httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2", size = 144189 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 }, +] + [[package]] name = "identify" version = "2.6.1" @@ -878,6 +985,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/22/2d/9c0b76f2f9cc0ebede1b9371b6f317243028ed60b90705863d493bae622e/ipywidgets-8.1.5-py3-none-any.whl", hash = "sha256:3290f526f87ae6e77655555baba4f36681c555b8bdbbff430b70e52c34c86245", size = 139767 }, ] +[[package]] +name = "isoduration" +version = "20.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321 }, +] + [[package]] name = "jedi" version = "0.19.1" @@ -911,6 +1030,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/91/29/df4b9b42f2be0b623cbd5e2140cafcaa2bef0759a00b7b70104dcfe2fb51/joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6", size = 301817 }, ] +[[package]] +name = "json5" +version = "0.9.25" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/59/51b032d53212a51f17ebbcc01bd4217faab6d6c09ed0d856a987a5f42bbc/json5-0.9.25.tar.gz", hash = "sha256:548e41b9be043f9426776f05df8635a00fe06104ea51ed24b67f908856e151ae", size = 40332 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/3c/4f8791ee53ab9eeb0b022205aa79387119a74cc9429582ce04098e6fc540/json5-0.9.25-py3-none-any.whl", hash = "sha256:34ed7d834b1341a86987ed52f3f76cd8ee184394906b6e22a1e0deb9ab294e8f", size = 30109 }, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595 }, +] + [[package]] name = "jsonschema" version = "4.23.0" @@ -926,6 +1063,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566", size = 88462 }, ] +[package.optional-dependencies] +format-nongpl = [ + { name = "fqdn" }, + { name = "idna" }, + { name = "isoduration" }, + { name = "jsonpointer" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "uri-template" }, + { name = "webcolors" }, +] + [[package]] name = "jsonschema-specifications" version = "2024.10.1" @@ -987,6 +1136,104 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c9/fb/108ecd1fe961941959ad0ee4e12ee7b8b1477247f30b1fdfd83ceaf017f0/jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", size = 28965 }, ] +[[package]] +name = "jupyter-events" +version = "0.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonschema", extra = ["format-nongpl"] }, + { name = "python-json-logger" }, + { name = "pyyaml" }, + { name = "referencing" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8d/53/7537a1aa558229bb0b1b178d814c9d68a9c697d3aecb808a1cb2646acf1f/jupyter_events-0.10.0.tar.gz", hash = "sha256:670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22", size = 61516 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/94/059180ea70a9a326e1815176b2370da56376da347a796f8c4f0b830208ef/jupyter_events-0.10.0-py3-none-any.whl", hash = "sha256:4b72130875e59d57716d327ea70d3ebc3af1944d3717e5a498b8a06c6c159960", size = 18777 }, +] + +[[package]] +name = "jupyter-lsp" +version = "2.2.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/b4/3200b0b09c12bc3b72d943d923323c398eff382d1dcc7c0dbc8b74630e40/jupyter-lsp-2.2.5.tar.gz", hash = "sha256:793147a05ad446f809fd53ef1cd19a9f5256fd0a2d6b7ce943a982cb4f545001", size = 48741 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/e0/7bd7cff65594fd9936e2f9385701e44574fc7d721331ff676ce440b14100/jupyter_lsp-2.2.5-py3-none-any.whl", hash = "sha256:45fbddbd505f3fbfb0b6cb2f1bc5e15e83ab7c79cd6e89416b248cb3c00c11da", size = 69146 }, +] + +[[package]] +name = "jupyter-server" +version = "2.14.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "argon2-cffi" }, + { name = "jinja2" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "jupyter-events" }, + { name = "jupyter-server-terminals" }, + { name = "nbconvert" }, + { name = "nbformat" }, + { name = "overrides" }, + { name = "packaging" }, + { name = "prometheus-client" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "pyzmq" }, + { name = "send2trash" }, + { name = "terminado" }, + { name = "tornado" }, + { name = "traitlets" }, + { name = "websocket-client" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0c/34/88b47749c7fa9358e10eac356c4b97d94a91a67d5c935a73f69bc4a31118/jupyter_server-2.14.2.tar.gz", hash = "sha256:66095021aa9638ced276c248b1d81862e4c50f292d575920bbe960de1c56b12b", size = 719933 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/e1/085edea6187a127ca8ea053eb01f4e1792d778b4d192c74d32eb6730fed6/jupyter_server-2.14.2-py3-none-any.whl", hash = "sha256:47ff506127c2f7851a17bf4713434208fc490955d0e8632e95014a9a9afbeefd", size = 383556 }, +] + +[[package]] +name = "jupyter-server-terminals" +version = "0.5.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "terminado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/d5/562469734f476159e99a55426d697cbf8e7eb5efe89fb0e0b4f83a3d3459/jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269", size = 31430 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa", size = 13656 }, +] + +[[package]] +name = "jupyterlab" +version = "4.2.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-lru" }, + { name = "httpx" }, + { name = "ipykernel" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyter-lsp" }, + { name = "jupyter-server" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "packaging" }, + { name = "setuptools" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4a/78/ba006df6edaa561fe40be26c35e9da3f9316f071167cd7cc1a1a25bd2664/jupyterlab-4.2.5.tar.gz", hash = "sha256:ae7f3a1b8cb88b4f55009ce79fa7c06f99d70cd63601ee4aa91815d054f46f75", size = 21508698 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/3f/24a0f0ce60959cfd9756a3291cd3a5581e51cbd6f7b4aa121f5bba5320e3/jupyterlab-4.2.5-py3-none-any.whl", hash = "sha256:73b6e0775d41a9fee7ee756c80f58a6bed4040869ccc21411dc559818874d321", size = 11641981 }, +] + [[package]] name = "jupyterlab-pygments" version = "0.3.0" @@ -996,6 +1243,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884 }, ] +[[package]] +name = "jupyterlab-server" +version = "2.27.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "jinja2" }, + { name = "json5" }, + { name = "jsonschema" }, + { name = "jupyter-server" }, + { name = "packaging" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0a/c9/a883ce65eb27905ce77ace410d83587c82ea64dc85a48d1f7ed52bcfa68d/jupyterlab_server-2.27.3.tar.gz", hash = "sha256:eb36caca59e74471988f0ae25c77945610b887f777255aa21f8065def9e51ed4", size = 76173 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4", size = 59700 }, +] + [[package]] name = "jupyterlab-widgets" version = "3.0.13" @@ -1535,6 +1800,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, ] +[[package]] +name = "notebook-shim" +version = "0.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307 }, +] + [[package]] name = "numba" version = "0.59.1" @@ -1594,6 +1871,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754 }, ] +[[package]] +name = "overrides" +version = "7.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832 }, +] + [[package]] name = "packaging" version = "24.1" @@ -1791,6 +2077,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/16/8f/496e10d51edd6671ebe0432e33ff800aa86775d2d147ce7d43389324a525/pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878", size = 218713 }, ] +[[package]] +name = "prometheus-client" +version = "0.21.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/54/a369868ed7a7f1ea5163030f4fc07d85d22d7a1d270560dab675188fb612/prometheus_client-0.21.0.tar.gz", hash = "sha256:96c83c606b71ff2b0a433c98889d275f51ffec6c5e267de37c7a2b5c9aa9233e", size = 78634 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/2d/46ed6436849c2c88228c3111865f44311cff784b4aabcdef4ea2545dbc3d/prometheus_client-0.21.0-py3-none-any.whl", hash = "sha256:4fa6b4dd0ac16d58bb587c04b1caae65b8c5043e85f778f42f5f632f6af2e166", size = 54686 }, +] + [[package]] name = "prompt-toolkit" version = "3.0.48" @@ -1981,6 +2276,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, ] +[[package]] +name = "python-json-logger" +version = "2.0.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4f/da/95963cebfc578dabd323d7263958dfb68898617912bb09327dd30e9c8d13/python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c", size = 10508 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/a6/145655273568ee78a581e734cf35beb9e33a370b29c5d3c8fee3744de29f/python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd", size = 8067 }, +] + [[package]] name = "pytz" version = "2024.2" @@ -2009,6 +2313,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/26/df/2b63e3e4f2df0224f8aaf6d131f54fe4e8c96400eb9df563e2aae2e1a1f9/pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd", size = 7974986 }, ] +[[package]] +name = "pywinpty" +version = "2.0.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/82/90f8750423cba4b9b6c842df227609fb60704482d7abf6dd47e2babc055a/pywinpty-2.0.14.tar.gz", hash = "sha256:18bd9529e4a5daf2d9719aa17788ba6013e594ae94c5a0c27e83df3278b0660e", size = 27769 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/09/56376af256eab8cc5f8982a3b138d387136eca27fa1a8a68660e8ed59e4b/pywinpty-2.0.14-cp310-none-win_amd64.whl", hash = "sha256:0b149c2918c7974f575ba79f5a4aad58bd859a52fa9eb1296cc22aa412aa411f", size = 1397115 }, + { url = "https://files.pythonhosted.org/packages/be/e2/af1a99c0432e4e58c9ac8e334ee191790ec9793d33559189b9d2069bdc1d/pywinpty-2.0.14-cp311-none-win_amd64.whl", hash = "sha256:cf2a43ac7065b3e0dc8510f8c1f13a75fb8fde805efa3b8cff7599a1ef497bc7", size = 1397223 }, + { url = "https://files.pythonhosted.org/packages/ad/79/759ae767a3b78d340446efd54dd1fe4f7dafa4fc7be96ed757e44bcdba54/pywinpty-2.0.14-cp312-none-win_amd64.whl", hash = "sha256:55dad362ef3e9408ade68fd173e4f9032b3ce08f68cfe7eacb2c263ea1179737", size = 1397207 }, + { url = "https://files.pythonhosted.org/packages/7d/34/b77b3c209bf2eaa6455390c8d5449241637f5957f41636a2204065d52bfa/pywinpty-2.0.14-cp313-none-win_amd64.whl", hash = "sha256:074fb988a56ec79ca90ed03a896d40707131897cefb8f76f926e3834227f2819", size = 1396698 }, +] + [[package]] name = "pyyaml" version = "6.0.2" @@ -2154,6 +2470,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, ] +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490 }, +] + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242 }, +] + [[package]] name = "rpds-py" version = "0.20.0" @@ -2342,6 +2679,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/83/11/00d3c3dfc25ad54e731d91449895a79e4bf2384dc3ac01809010ba88f6d5/seaborn-0.13.2-py3-none-any.whl", hash = "sha256:636f8336facf092165e27924f223d3c62ca560b1f2bb5dff7ab7fad265361987", size = 294914 }, ] +[[package]] +name = "send2trash" +version = "1.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/3a/aec9b02217bb79b87bbc1a21bc6abc51e3d5dcf65c30487ac96c0908c722/Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf", size = 17394 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9", size = 18072 }, +] + [[package]] name = "setuptools" version = "75.2.0" @@ -2587,6 +2933,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f", size = 35252 }, ] +[[package]] +name = "terminado" +version = "0.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess", marker = "os_name != 'nt'" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154 }, +] + [[package]] name = "threadpoolctl" version = "3.5.0" @@ -2644,6 +3004,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359 }, ] +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20241003" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/f8/f6ee4c803a7beccffee21bb29a71573b39f7037c224843eff53e5308c16e/types-python-dateutil-2.9.0.20241003.tar.gz", hash = "sha256:58cb85449b2a56d6684e41aeefb4c4280631246a0da1a719bdbe6f3fb0317446", size = 9210 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/d6/ba5f61958f358028f2e2ba1b8e225b8e263053bd57d3a79e2d2db64c807b/types_python_dateutil-2.9.0.20241003-py3-none-any.whl", hash = "sha256:250e1d8e80e7bbc3a6c99b907762711d1a1cdd00e978ad39cb5940f6f0a87f3d", size = 9693 }, +] + [[package]] name = "typing-extensions" version = "4.12.2" @@ -2662,6 +3031,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586 }, ] +[[package]] +name = "uri-template" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140 }, +] + [[package]] name = "urllib3" version = "2.2.3" @@ -2791,6 +3169,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 }, ] +[[package]] +name = "webcolors" +version = "24.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/f8/53150a5bda7e042840b14f0236e1c0a4819d403658e3d453237983addfac/webcolors-24.8.0.tar.gz", hash = "sha256:08b07af286a01bcd30d583a7acadf629583d1f79bfef27dd2c2c5c263817277d", size = 42392 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/33/12020ba99beaff91682b28dc0bbf0345bbc3244a4afbae7644e4fa348f23/webcolors-24.8.0-py3-none-any.whl", hash = "sha256:fc4c3b59358ada164552084a8ebee637c221e4059267d0f8325b3b560f6c7f0a", size = 15027 }, +] + [[package]] name = "webencodings" version = "0.5.1" @@ -2800,6 +3187,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774 }, ] +[[package]] +name = "websocket-client" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826 }, +] + [[package]] name = "widgetsnbextension" version = "4.0.13" From e4feee80109c40f5470942fcf2a39ec6462f91e5 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 29 Oct 2024 14:24:11 -0400 Subject: [PATCH 8/9] Add some commented out loopnest code --- python/egglog/exp/array_api_loopnest.py | 33 ++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/python/egglog/exp/array_api_loopnest.py b/python/egglog/exp/array_api_loopnest.py index c512b6a2..c12c67e5 100644 --- a/python/egglog/exp/array_api_loopnest.py +++ b/python/egglog/exp/array_api_loopnest.py @@ -141,9 +141,40 @@ def linalg_norm(X: NDArray, axis: TupleIntLike) -> NDArray: x = egraph.let("x", val.shape[2]) # egraph.display(n_inline_leaves=0) # egraph.extract(x) -# egraph.saturate(array_api_ruleset, expr=val.shape[2], split_functions=[Int, TRUE, FALSE], n_inline_leaves=2) +# egraph.saturate(array_api_ruleset, expr=x, split_functions=[Int, TRUE, FALSE], n_inline_leaves=0) # egraph.run(array_api_ruleset.saturate()) +# egraph.extract(x) # egraph.display() # %% + +# x = xs[-2] +# # %% +# decls = x.__egg_decls__ +# # RuntimeExpr.__from_values__(x.__egg_decls__, x.__egg_typed_expr__.expr.args[1].expr.args[1]) + +# # %% +# # x.__egg_typed_expr__.expr.args[1].expr.args[1] # %% + +# # %% +# # egraph.extract(RuntimeExpr.__from_values__(x.__egg_decls__, x.__egg_typed_expr__.expr.args[1].expr.args[1])) + + +# from egglog import pretty + +# decl = ( +# x.__egg_typed_expr__.expr.args[1] +# .expr.args[2] +# .expr.args[0] +# .expr.args[1] +# .expr.call.args[0] +# .expr.call.args[0] +# .expr.call.args[0] +# ) + +# # pprint.pprint(decl) + +# print(pretty.pretty_decl(decls, decl.expr)) + +# # %% From 2e089f238f1f1addb1106a77e9edf7b196131c5e Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 29 Oct 2024 14:27:46 -0400 Subject: [PATCH 9/9] remove temporary saturate debugging code --- python/egglog/egraph.py | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/python/egglog/egraph.py b/python/egglog/egraph.py index 75d21ec4..1cc41350 100644 --- a/python/egglog/egraph.py +++ b/python/egglog/egraph.py @@ -1369,22 +1369,9 @@ def saturate( Saturate the egraph, running the given schedule until the egraph is saturated. It serializes the egraph at each step and returns a widget to visualize the egraph. """ - # from .visualizer_widget import VisualizerWidget - - last_expr = None - index = 0 - exprs = [] + from .visualizer_widget import VisualizerWidget def to_json() -> str: - nonlocal last_expr, index - if expr is not None: - extracted = self.extract(expr) - # s = str(extracted) - if extracted.__egg_typed_expr__ != last_expr: - exprs.append(extracted) - last_expr = extracted.__egg_typed_expr__ - print(f"# {index}:\n", str(extracted), "\n") - index += 1 return self._serialize(**kwargs).to_json() egraphs = [to_json()] @@ -1392,8 +1379,7 @@ def to_json() -> str: while self.run(schedule or 1).updated and i < max: i += 1 egraphs.append(to_json()) - # VisualizerWidget(egraphs=egraphs).display_or_open() - return exprs + VisualizerWidget(egraphs=egraphs).display_or_open() @classmethod def current(cls) -> EGraph: