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

Add Reactant #265

Open
wsmoses opened this issue May 17, 2024 · 16 comments
Open

Add Reactant #265

wsmoses opened this issue May 17, 2024 · 16 comments
Labels
backend Related to one or more autodiff backends

Comments

@wsmoses
Copy link

wsmoses commented May 17, 2024

It's not quite an AD engine in its own right, but given how it traces things and can make for much better performance/compatibility, and can be used with an AD engine, it seems like a natural fit.

@gdalle gdalle added the backend Related to one or more autodiff backends label May 17, 2024
@gdalle
Copy link
Member

gdalle commented May 17, 2024

Why not but I don't understand what the package does or how it would fit within DI, so you'll have to hold my hand on this one ^^

@wsmoses
Copy link
Author

wsmoses commented May 17, 2024

Yeah so basically, Reactant exports a compile utility which takes a julia function and arguments, and compiles it to a nice/fast version of it. It does require that all data one cares about to be passed in using ConcreteRArrays rather than Ararys [and structs of those/etc]. We do have a tracer utility which will take an arg and auotmatically changes arrays to ConcreteRArrays for you though.

This can obviously compile code with an autodiff call on the inside, such as Enzyme. See here: https://github.com/EnzymeAD/Reactant.jl/blob/292dc03593ceb1a7a1f022fd7d3289bd69b000b5/test/basic.jl#L81. Enzyme usage should end up with quite good performance since the fancy optimizations that Reactant applies will be able to interoperate with AD.

@wsmoses
Copy link
Author

wsmoses commented May 17, 2024

We also now have a brief tldr in the readme: https://github.com/EnzymeAD/Reactant.jl/tree/main

@gdalle
Copy link
Member

gdalle commented May 17, 2024

So how would you see this in the context of DI? As a variant of the Enzyme backend which Reactant-compiles the function during preparation?

@wsmoses
Copy link
Author

wsmoses commented May 17, 2024 via email

@gdalle
Copy link
Member

gdalle commented May 17, 2024

And do what with it? Compile and convert everything before and after use?

@wsmoses
Copy link
Author

wsmoses commented May 17, 2024

Yup

@gdalle
Copy link
Member

gdalle commented May 18, 2024

I would welcome a PR with an example!

@wsmoses
Copy link
Author

wsmoses commented Jun 18, 2024

I'm not quite sure how to make an example PR, but here's an example from our tests: https://github.com/EnzymeAD/Reactant.jl/blob/59d9304948cc7e28acdd4351db5e069d62a4f4ec/test/basic.jl#L92

function sumcos(x)
    return sum(cos.(x))
end

function resgrad_ip(x)
    dx = Enzyme.make_zero(x)
    res = Enzyme.autodiff(ReverseWithPrimal, sumcos, Active, Duplicated(x, dx))
    return (res, dx)
end

 c = Reactant.ConcreteRArray(ones(3, 2))
    f = Reactant.compile(resgrad_ip, (c,))
    orig, r = f(c)

    @test orig[2]  sum(cos.(ones(3, 2)))
    @test r  -sin.(ones(3, 2))

Essentially you have to convert all inputs to ConcreteRarrays, then compile your desired function (which in this case will call an autodiff tool).

Happy to hop on a call or help however else!

This would be really great to get in and would give me a lot more use cases for DI.

Also fun fact the Reactant backend wouldn't suffer from any potential closure issues (since it would trace closures out anyways)

@gdalle
Copy link
Member

gdalle commented Jun 19, 2024

I'm open to testing it but I can't do much until it is registered

@wsmoses
Copy link
Author

wsmoses commented Jun 19, 2024

oh it's been registered for a while now!

@gdalle
Copy link
Member

gdalle commented Jun 19, 2024

My bad, I only checked the GitHub repo and the releases aren't tagged there

@gdalle
Copy link
Member

gdalle commented Jun 20, 2024

I wonder how to add this to DI with as little code duplication as possible. I see several options:

  • A backend wrapper ReactantBackend(AutoSomething)
  • A function wrapper ReactantFunction(f)
  • An option in the preparation prepare_operator(f, backend, x; reactant=true)

The first one seems easier to just put in a Reactant.jl extension

@gdalle
Copy link
Member

gdalle commented Nov 23, 2024

@wsmoses you no longer think this can be useful?

@wsmoses
Copy link
Author

wsmoses commented Nov 24, 2024

it might be, but it's also not really the right abstraction (e.g. you ought be able to @compile outside of any DI call as it has nothing to do with AD).

Of course it makes it easier to use via DI and enables the use of Enzyme [per other discussions], but also it's not really critical so I closed.

@gdalle
Copy link
Member

gdalle commented Jan 12, 2025

Switching the discussion to the proper issue to avoid cluttering OptimizationBase. @wsmoses could you elaborate on what you meant over there by an array wrapper for eg CUDA or Reactant, and why it could be useful?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend Related to one or more autodiff backends
Projects
None yet
Development

No branches or pull requests

2 participants