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

active_reg_inner returns DupState for immutable struct with untyped field #2039

Closed
danielwe opened this issue Oct 31, 2024 · 3 comments
Closed

Comments

@danielwe
Copy link
Contributor

Consider this:

julia> struct Foo
           x
       end

julia> Enzyme.Compiler.active_reg_inner(Foo, (), nothing)
DupState::ActivityState = 2

julia> Enzyme.Compiler.active_reg_inner(Foo, (), nothing, Val(true))  # justActive
AnyState::ActivityState = 0

The way I've understood it, DupState implies that all differentiable values reachable from an object can be mutated, i.e., that there's some mutable container along the chain of references from the object to each differentiable value. But this isn't known from the type of Foo. The simplest counterexample is Foo(1.0). Then again, it could be true, like in Foo([1.0]). Wouldn't the appropriate return here be MixedState, signaling that you should be prepared for both mutable and immutable values?

@wsmoses
Copy link
Member

wsmoses commented Oct 31, 2024 via email

@wsmoses wsmoses closed this as completed Oct 31, 2024
@wsmoses
Copy link
Member

wsmoses commented Oct 31, 2024

No because the float variable must be boxed (and thus duplicated)

@danielwe
Copy link
Contributor Author

Quick follow-up if you can spare another second, just to help my understanding:

I get that the value is held in a box, so you can mutate instances of Foo from the LLVM side or with some Ref/pointer shenanigans. But Julia seems to go to great lengths to hide this implementation detail, to the point where Foo(1.0) === Foo(1.0) is true. Doesn't this imply that mutating the boxed value would violate compiler assumptions and could wreak havoc, say if you do reverse mode autodiff with a Duplicated(Foo(0.0), Foo(0.0)) argument?

Anyway, I notice that this doesn't currently work, even with mutable struct Foo; x; end and/or putting the Foo(0.0) in a single-element vector, so perhaps the answer is simply that untyped fields aren't compatible with Enzyme?

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

No branches or pull requests

2 participants