Skip to content

Commit 5be178b

Browse files
committed
hacks
1 parent a9b0b9a commit 5be178b

3 files changed

Lines changed: 35 additions & 82 deletions

File tree

effectful/handlers/jax/monoid.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,16 @@ def reduce(self, monoid, body, streams):
174174
if typeof(body) is not jax.Array:
175175
return fwd()
176176

177-
# delta bodies belong to ReduceDeltaIndependent
178-
if isinstance(body, Term) and (body.op is delta or _is_monoid_plus(body.op)):
179-
return fwd()
177+
if isinstance(body, Term):
178+
# delta bodies belong to ReduceDeltaIndependent
179+
if body.op is delta:
180+
return fwd()
181+
if _is_monoid_plus(body.op):
182+
# factorizable bodies get factored
183+
factors = body.args
184+
factor_fvs = [fvsof(f) for f in factors]
185+
if not all(k in fvs for fvs in factor_fvs for k in streams):
186+
return fwd()
180187

181188
body_fvs = fvsof(body)
182189
used = [

effectful/ops/monoid.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,22 @@ def reduce(self, monoid, body, streams):
828828
return result
829829

830830

831+
class PlusInf(ObjectInterpretation):
832+
"""Workaround for the inability to give Monoid.plus(x, inf) a type."""
833+
834+
@implements(Monoid.plus)
835+
def plus(self, monoid, *args):
836+
if monoid in (Sum, Max) and any(
837+
not isinstance(x, Term) and x == float("inf") for x in args
838+
):
839+
return float("inf")
840+
if monoid in (Sum, Min) and any(
841+
not isinstance(x, Term) and x == -float("inf") for x in args
842+
):
843+
return -float("inf")
844+
return fwd()
845+
846+
831847
class _ExtensibleInterpretation(UserDict, Interpretation):
832848
def extend(self, *intps: Interpretation) -> typing.Self:
833849
for intp in intps:
@@ -859,6 +875,7 @@ def extend(self, *intps: Interpretation) -> typing.Self:
859875
ArgMinPlus(),
860876
ArgMaxPlus(),
861877
CartesianProductPlus(),
878+
PlusInf(),
862879
)
863880
"""``NormalizeIntp``applies pure-Term rewrites (associativity, distributivity,
864881
identity elimination, fusion, factorization, etc.).

tests/test_handlers_jax_monoid.py

Lines changed: 8 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -333,12 +333,10 @@ def test_reduce_contraction_single(backend: JaxBackend):
333333
)
334334

335335
lhs = Sum.reduce(Product.plus(A(i()), B(i())), {i: I()})
336-
rhs = Product.plus(
337-
jnp.tensordot(
338-
bind_dims(A(unbind_dims(I(), i)), i),
339-
bind_dims(B(unbind_dims(I(), i)), i),
340-
axes=((0,), (0,)),
341-
)
336+
rhs = jnp.tensordot(
337+
bind_dims(A(unbind_dims(I(), i)), i),
338+
bind_dims(B(unbind_dims(I(), i)), i),
339+
axes=((0,), (0,)),
342340
)
343341
backend.check_rewrite(lhs=lhs, rhs=rhs, rule=ReduceSumProductContraction())
344342

@@ -351,79 +349,10 @@ def test_reduce_contraction_double(backend: JaxBackend):
351349
)
352350

353351
lhs = Sum.reduce(Product.plus(A(i(), j()), B(i(), j())), {i: I(), j: J()})
354-
rhs = Product.plus(
355-
jnp.tensordot(
356-
bind_dims(A(unbind_dims(I(), i), unbind_dims(J(), j)), i, j),
357-
bind_dims(B(unbind_dims(I(), i), unbind_dims(J(), j)), i, j),
358-
axes=((0, 1), (0, 1)),
359-
)
360-
)
361-
backend.check_rewrite(lhs=lhs, rhs=rhs, rule=ReduceSumProductContraction())
362-
363-
364-
def test_reduce_contraction_multi_factor(backend: JaxBackend):
365-
i, j = backend.define_vars("i", "j", ret="scalar")
366-
I, J = backend.define_vars("I", "J", ret="stream")
367-
B = backend.define_vars(
368-
"B", arg_types=(backend.scalar_typ, backend.scalar_typ), ret="scalar"
369-
)
370-
A, C = backend.define_vars("A", "C", arg_types=(backend.scalar_typ,), ret="scalar")
371-
372-
lhs = Sum.reduce(Product.plus(A(i()), B(i(), j()), C(j())), {i: I(), j: J()})
373-
rhs = Product.plus(
374-
jnp.tensordot(
375-
bind_dims(
376-
jnp.tensordot(
377-
bind_dims(A(unbind_dims(I(), i)), i),
378-
bind_dims(B(unbind_dims(I(), i), unbind_dims(J(), j)), i),
379-
axes=((0,), (0,)),
380-
),
381-
j,
382-
),
383-
bind_dims(C(unbind_dims(J(), j)), j),
384-
axes=((0,), (0,)),
385-
)
386-
)
387-
backend.check_rewrite(lhs=lhs, rhs=rhs, rule=ReduceSumProductContraction())
388-
389-
390-
def test_reduce_contraction_shared_only(backend: JaxBackend):
391-
i, j, k = backend.define_vars("i", "j", "k", ret="scalar")
392-
I, J, K = backend.define_vars("I", "J", "K", ret="stream")
393-
A = backend.define_vars(
394-
"A",
395-
arg_types=(backend.scalar_typ, backend.scalar_typ, backend.scalar_typ),
396-
ret="scalar",
397-
)
398-
B, C = backend.define_vars(
399-
"B", "C", arg_types=(backend.scalar_typ, backend.scalar_typ), ret="scalar"
400-
)
401-
402-
lhs = Sum.reduce(
403-
Product.plus(A(i(), j(), k()), B(i(), j()), C(j(), k())),
404-
{i: I(), j: J(), k: K()},
405-
)
406-
rhs = Product.plus(
407-
jnp.tensordot(
408-
bind_dims(
409-
jnp.tensordot(
410-
bind_dims(
411-
A(
412-
unbind_dims(I(), i),
413-
unbind_dims(J(), j),
414-
unbind_dims(K(), k),
415-
),
416-
i,
417-
),
418-
bind_dims(B(unbind_dims(I(), i), unbind_dims(J(), j)), i),
419-
axes=((0,), (0,)),
420-
),
421-
j,
422-
k,
423-
),
424-
bind_dims(C(unbind_dims(J(), j), unbind_dims(K(), k)), j, k),
425-
axes=((0, 1), (0, 1)),
426-
)
352+
rhs = jnp.tensordot(
353+
bind_dims(A(unbind_dims(I(), i), unbind_dims(J(), j)), i, j),
354+
bind_dims(B(unbind_dims(I(), i), unbind_dims(J(), j)), i, j),
355+
axes=((0, 1), (0, 1)),
427356
)
428357
backend.check_rewrite(lhs=lhs, rhs=rhs, rule=ReduceSumProductContraction())
429358

0 commit comments

Comments
 (0)