Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make_zero! for immutable #1958

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

make_zero! for immutable #1958

wants to merge 5 commits into from

Conversation

vchuravy
Copy link
Member

Recurse through the immutable and set the mutable fields to zero.

@danielwe
Copy link
Contributor

danielwe commented Oct 10, 2024

Hi, just want to mention that I've spent a lot of time with make_zero! lately for #1852, which is almost ready. There are several bugs (missing branches in some make_zero_immutable! methods, several in(seen, prev) that should be in(prev, seen), et cetera), but I'm not sure a separate !ismutable branch in the generic method is needed. These cases should go through line 404 398 (EDIT: changed line # to refer to the pre-PR state). What's the error you're seeing?

You can check out this commit on a branch in my fork for fixes to all the bugs I found in make_zero and make_zero!: danielwe@7a6ca9f. I haven't PRd it because it's redundant with #1852, but if a stopgap solution is needed, you might find the fix you need there.

@vchuravy
Copy link
Member Author

What's the error you're seeing?

If prev is an immutable the line

setfield!(prev, i, make_zero_immutable!(xi, seen))

in the generic handler will fail.

@danielwe
Copy link
Contributor

danielwe commented Oct 10, 2024

If prev is an immutable the line

setfield!(prev, i, make_zero_immutable!(xi, seen))

in the generic handler will fail.

That's only the case if the immutable contains immutable differentiable values, like (; a=1.0, b=[1.0]) (ActiveState or MixedState), in which case make_zero! should fail anyway. If make_zero! succeeds on an immutable type, that's because every differentiable value is contained within mutable storage, like (; a=[1.0], b=[1.0]) and the test case in this PR (DupState or, trivially, AnyState). In these cases, you will never hit the setfield! branch, you'll hit the branch below that's recursively calling make_zero!.

I.e., the test case added in this PR would never hit the setfield! branch anyway.

However, if you have a MixedState NamedTuple contained within a mutable container, such as [(; a=1.0, b=[1.0])], and call make_zero! on the outer container, then you'll hit the make_zero_immutable!(::Type{<:NamedTuple}, ...) method, and this one has a bug where it fails to call back into make_zero! for the mutable fields. That's the bug fixed in this part of the commit I linked: danielwe@7a6ca9f#diff-10924b07e20c4a235afd58dea795108f564d5f535318adb73991e4e57144e09dR211-R223

Is this what you've been running into?

@danielwe
Copy link
Contributor

Just realized the proposed fix here could also be a way to mask #1935 (because the bug in active_reg_inner makes the recursion take the wrong branch and call make_zero! when it should have called make_zero_immutable!), but I think the proper fix for that should be #1936 or something similar. The fix proposed here enables silent bugs where make_zero! fails to throw an error on unsupported types, while the bug in active_reg_inner remains unaddressed and may show up in other contexts.

@danielwe
Copy link
Contributor

danielwe commented Oct 11, 2024

...and any issue addressed by this PR that isn't caused by #1935 should be fixed by #1961. If that's not the case, please send me an MWE so I can fix that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants