GithubHelp home page GithubHelp logo

Comments (5)

lockwo avatar lockwo commented on June 9, 2024 1

Hmmm I see. This is a fix, by making a wrapper object basically for the tuple singleton: #717. This is definitely the craziest edge case to write this much code for lol

from equinox.

lockwo avatar lockwo commented on June 9, 2024

Not 100% sure on the source, but one fix is to force it to recognize tuples as endpoints, via

import equinox as eqx


class M(eqx.Module):
    a: tuple
    b: tuple

    def __init__(self):
        self.a = ()
        self.b = (1,)


eqx.tree_at(lambda m: m.a, M(), (), is_leaf=lambda x: x == ())

from equinox.

patrick-kidger avatar patrick-kidger commented on June 9, 2024

Interesting! Looks like Python actually uses the exact same object for tuple literals:

() is ()  # True
(1,) is (1,)  # True

So the logic inside eqx.tree_at works by requiring that for any two nodes x, y in the PyTree, that x is not y. This is how it can identify what to replace. (Here I use "node" to refer to both composite nodes and leaves.)

Now specifically leaves frequently fail this (e.g. x = [4, 4]; x[0] is x[1] # True), so we make this work by first doing a pytree = jtu.tree_map(Wrapper, pytree) to wrap up the leaves. No big deal.

And until this point, there haven't been any examples of composite nodes which fail the x is not y check. Now it seems we have one! This is why two tuples are specifically what is required to bump into this issue.

If anyone feels like tackling this in the near future then I'd be happy to take a pull request.

from equinox.

lockwo avatar lockwo commented on June 9, 2024

Is this something that needs a fix, it seems like its working as it should? This exists because an empty tuple is a singleton in CPython, so only 1 ever exists in memory (so all () have the same id) (https://stackoverflow.com/questions/14135542/how-is-tuple-implemented-in-cpython/). If you have something like

class M(eqx.Module):
    a: tuple
    b: tuple

    def __init__(self):
        self.a = (1,)
        self.b = (1,)

this works because the id's are different. In my mind, equinox is behaving as it should, the where function is underspecified since it points to two objects in memory and its hard to think of a workaround that works for making tuples which are identical in memory that doesn't break other things that are equal in memory (outside of a hardcoded if x == () or something). Even if there was a workaround, I think it wouldn't be ideal for two reasons 1) it's such very much an edge case, 2) people who knew about tuples being singletons going into equinox (I just learned it) would then be surprised by the behavior because now equinox is going against what CPython does.

from equinox.

patrick-kidger avatar patrick-kidger commented on June 9, 2024

So I think of eqx.tree_at as just being a "please change the node at this path in the PyTree". The fact that it goes via CPython's id is an implementation detail, not its defining characteristic.

I think on that basis this is a minor bug. Though as you say, this is a very very edge case with a loud failure and an easy work-around, so it's not one I'm too worried by overall!

from equinox.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.