# Reddit discussion: limitations of Zygote

**URL:** https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982
**Category:** Machine Learning
**Created:** [April 3, 2020, 8:32pm UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982 "2020-04-03T20:32:19Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![jaynick](https://avatars.discourse-cdn.com/v4/letter/j/71c47a/32.png) [@jaynick](https://discourse.julialang.org/u/jaynick)
#### Post date: [April 3, 2020, 8:32pm UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/1 "2020-04-03T20:32:19Z")

</div>

There is a [reddit discussion](https://www.reddit.com/r/MachineLearning/comments/ftvcap/n_swift_googles_bet_on_differentiable_programming/) of the swift/tensorflow project that has a couple comments about Julia.

I am interested in this statement - to what extent is this true?

> If the end goal is to “differentiate all the things”, where by things we mean all Julia packages, then Zygote might be the answer. Problem is that, from what I understand of it, it can’t really differentiate all current Julia packages unless they all adhere to a strict coding format or either the compiler is significantly altered to cope with what Zygote expects.

The Zygote docs do not seem to mention such coding format.

The discussion also says

> IIRC SciML is about differential equations, not differentiable programming.

which I think maybe is not true in theory, but in practice true (I gather that right now the focus of the Flux community is mainly differential equations, not so much interest for general ML?)

---

<div class="post-metadata">

### Author: ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)
#### Post date: [April 4, 2020, 12:57am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/2 "2020-04-04T00:57:17Z")

</div>

I never understood what it means to “differentiate a program”.  
From calc I know what it means to differentiate a differentiable function f:R^n \to R^m.  
I realize we can sometimes think of a program as a function, but I don’t see how to compute it’s derivative.

@MikeInnes @ChrisRackauckas et al have a [paper](https://arxiv.org/pdf/1907.07587.pdf) I’ve seen mentioned often, but I never understood it.

The guy who began the reddit discussion has a [post on differentiable programming](https://tryolabs.com/blog/2020/04/02/swift-googles-bet-on-differentiable-programming/) where he writes:

> In a nutshell, differentiable programming is a programming paradigm in which your program itself can be differentiated. This allows you to set a certain objective you want to optimize, have your program automatically calculate the gradient of itself with regards to this objective, and then fine-tune itself in the direction of this gradient…

He gives an example (I’ll paraphrase)

```julia
cube(x) = x^3
cube𝛁 = gradient(of: cube)
cube(2) // 8.0
cube𝛁(2) // 12.0

```

I’m confused, this is just the derivative of a differentiable function f:R \to R.  
He continues

> There are no libraries or external code being used here, `gradient` is simply a new function that is being introduced by the S4TF team into the Swift language…  
> This is Swift’s big new feature. You can take arbitrary Swift code and, as long as it’s differentiable, automatically calculate its gradient. The code above has no imports or weird dependencies, it’s just plain Swift.

Either:

1. we are “just” computing derivatives of differentiable functions (in a convenient way that works w/ all libraries in the language)
2. I’m even more confused than I begin

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [April 4, 2020, 1:05am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/3 "2020-04-04T01:05:20Z")

</div>

It’s 1, with the key insight being how much of a pain that is.  
Have you ever ran the chain rule through a for loop? What about recursion? It’s not fun or easy.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [April 4, 2020, 1:05am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/4 "2020-04-04T01:05:32Z")

</div>

> [@Albert\_Zevelev](#):
>
> we are “just” computing derivatives of differentiable functions (in a convenient way that works w/ all libraries in the language)

It’s this one. I describe the key of differentiable programming as really just knowing that you can get derivatives from an arbitrary program here in a more example-oriented way:

[![](https://global.discourse-cdn.com/julialang/original/3X/1/e/1ef6e503a18bde436ef492c60c03851bdfd138a5.jpeg "Generalized Physics-Informed Learning through Language-Wide Differentiable Programming by Rackauckas") ](https://www.youtube.com/watch?v=SEhMWkgcTOI)

---

<div class="post-metadata">

### Author: ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)
#### Post date: [April 4, 2020, 1:50am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/5 "2020-04-04T01:50:13Z")

</div>

Can all differentiable functions in Julia be differentiated w/ Zygote.jl?  
If so, the only difference I see is that you don’t need to load a library to compute a gradient in Swift, whereas you need `using Zygote` in Julia…

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [April 4, 2020, 2:01am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/6 "2020-04-04T02:01:46Z")

</div>

Zygote currently can not deal with mutation, but that is WIP.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [April 4, 2020, 2:06am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/7 "2020-04-04T02:06:15Z")

</div>

IIRC, In Swift you have to mark things as `@differentiable`, so you do need buy-in from the package authors. I can see this being an issue when you want to throw some messaging protocols like webservers in the loop.

But I don’t really see these kinds of details as an actual big deal with differentiable programming. I think the bigger deal is what other codes are working with your differentiable programming world that you can plug together. With Julia, that includes things like stiff delay differential equation solvers, verified commercial pharmacometric simulation platforms, climate models, full-featured robotics simulation libraries I really think that what matters the most is ChainRules.jl and the culture of pervasive derivative rules and overloading everything for highest performance derivatives.

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [April 4, 2020, 2:15am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/8 "2020-04-04T02:15:44Z")

</div>

I think it is telling that when I google Swift the only things I can find are articles about app development.

---

<div class="post-metadata">

### Author: ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)
#### Post date: [April 4, 2020, 2:42am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/9 "2020-04-04T02:42:40Z")

</div>

@tbeason the narrative I keep hearing (not sure I understand):

1. the only two languages where you can differentiate all (differentiable) functions are Julia & Swift
2. Julia is the only one of those two w/ extensive scientific libraries.  
Swift is intended for developing apps for iOS/MacOS.

There is a beautiful example in the paper where they differentiate sin(x)

```julia
#Define sin(x) through its Taylor series
function s(x)
    t = 0.0
    sign = -1.0
    for i in 1:19
        if isodd(i)
            newterm = x^i/factorial(i)
            abs(newterm)<1e-8 && return t
            println("i=",i)
            sign = -sign
            t += sign * newterm
        end
    end 
    return t
end
#
using Zygote, ForwardDiff
cos(1.0)
ForwardDiff.derivative(s, 1.0) # Forward Mode AD
Zygote.gradient(s, 1.0) # Reverse Mode AD

#compare with
ForwardDiff.derivative(sin, 1.0) # Forward Mode AD
Zygote.gradient(sin, 1.0) # Reverse Mode AD

```

While both s(x) & sin(x) are differentiable functions, s(x) is written w/ standard Julia programming tools. (Perhaps this is why they call it “differentiable programming” 🤷‍♂️)

I think the point is that it is much harder to differentiate functions like s(x) in R/Python etc

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 5, 2020, 11:54am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/10 "2020-04-05T11:54:37Z")

</div>

> [@Albert\_Zevelev](#):
>
> think the point is that it is much harder to differentiate functions like s(x) in R/Python etc

AD has a reasonably long history (in the context of computer programming), so in a sense it is not hard to just apply _some_ form of AD if the only concern is feasibility. A lot of languages provide some solution to AD; the operator overloading approach should work fine with `s(x)` in most languages.

However, for practical programs, convenience (don’t need a source-to-source transformer like [ADIFOR](https://www.mcs.anl.gov/research/projects/adifor/), or keep track of duals/adjoints manually), speed and memory efficiency are relevant concerns. The great thing about the approach Zygote has chosen is that it provides a code transformation solution that meshes really well with Julia’s compiler model.

However, apparently few people read [the docs](https://fluxml.ai/Zygote.jl/dev/), which clearly state that

> We’re still in beta so expect some adventures.

At this point, Zygote is for users who are willing to tolerate the fact that they need to program in a certain way to have the code transformation work. This is becoming less and less restrictive, but still remains relevant.

---

<div class="post-metadata">

### Author: ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)
#### Post date: [April 5, 2020, 12:07pm UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/11 "2020-04-05T12:07:50Z")

</div>

> [@Tamas\_Papp](#):
>
> convenience (don’t need a source-to-source transformer like [ADIFOR](https://www.mcs.anl.gov/research/projects/adifor/),

From the ADIFOR website:

> Users wishing to use ADIFOR for educational and non-profit research or for the purpose of commercial evaluation can obtain ADIFOR at no cost by doing the following:
> 
> 1. Fill out and electronically submit a copy of the [ADIFOR Request Form](https://www.mcs.anl.gov/research/projects/adifor/AdiforRequestForm.html).
> 2. Download a copy of the [ADIFOR Public License](https://www.mcs.anl.gov/research/projects/adifor/AdiforPublicLicense.html) (see [Help with File Downloading](https://www.mcs.anl.gov/research/projects/adifor/HowToDownload.html) if necessary.).
> 3. Read and sign the license. Students should have their advisor sign the license.
> 4. Fax the signed license to:
> 
> - Paul Hovland at +1-630-252-5986 if you are registering at Argonne.

Aside from not being free software, I’d spend some time looking for alternatives that don’t require I print out, sign, and then fax a license agreement.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 5, 2020, 12:14pm UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/12 "2020-04-05T12:14:44Z")

</div>

That nicely underlines my point about convenience 😉 I just linked it for historical reasons.

---

<div class="post-metadata">

### Author: ![jaynick](https://avatars.discourse-cdn.com/v4/letter/j/71c47a/32.png) [@jaynick](https://discourse.julialang.org/u/jaynick)
#### Post date: [April 5, 2020, 11:46pm UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/13 "2020-04-05T23:46:52Z")

</div>

> [@Tamas\_Papp](#):
>
> Zygote is for users who are willing to tolerate the fact that they need to program in a certain way to have the code transformation work.

This is my question: **what are** these restrictions on how we need to program?  
I think they are not described in the docs anywhere?

The only thing I have heard of is that arrays cannot be mutated (and I think even that is not in the docs?). Are there other restrictions?

As someone who “just wants to develop algorithms”, should I be using Zygote or tracker?

---

<div class="post-metadata">

### Author: ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)
#### Post date: [April 6, 2020, 12:02am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/14 "2020-04-06T00:02:58Z")

</div>

Have a look at the issue page of Zygote

> **[Issues · FluxML/Zygote.jl](https://github.com/FluxML/Zygote.jl/issues)**
>
> 21st century AD. Contribute to FluxML/Zygote.jl development by creating an account on GitHub.

While this might not be good strategy to learn how to write a program that Zygote can handle, it will show you that there are a ton of things that will trip you up, and any non-trivial program is likely to require some workarounds and quite a lot of manually defined adjoints (the standard answer to many issues is “just define the adjoint”).

A particularly uncomfortable issue with Zygote is that many bugs lead to segfaults causing julia to crash and not always give you much helpful info (I’m debugging one of these as I write this).

ReverseDiff.jl or Tracker.jl are probably easier to get going at the moment.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 6, 2020, 5:47am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/15 "2020-04-06T05:47:49Z")

</div>

> [@jaynick](#):
>
> This is my question: **what are** these restrictions on how we need to program?  
> I think they are not described in the docs anywhere?

To a certain extent it is, eg [the introduction](https://fluxml.ai/Zygote.jl/dev/#Taking-Gradients-1) mentions that arrays should not be mutated but it is WIP.

I think it is best to understand that it is _work in progress_: don’t use it unless you are OK with encountering limitations (not necessarily documented), corner cases, issues, making an MWE, reporting an issue, and an occasional PR; and of course defining your own adjoints when necessary. As @baggepinnen, the issue tracker is very useful.

If you are not so adventurous, at the moment I would recommend Tracker, or even ReverseDiff or ForwardDiff, depending on your use case.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 14, 2020, 9:12am UTC](https://discourse.julialang.org/t/reddit-discussion-limitations-of-zygote/36982/16 "2020-04-14T09:12:09Z")

</div>

> [@Albert\_Zevelev](#):
>
> @MikeInnes @ChrisRackauckas et al have a [paper](https://arxiv.org/pdf/1907.07587.pdf) I’ve seen mentioned often, but I never understood it.

I have read

> **[A Differentiable Programming System to Bridge Machine Learning and Scientific...](https://arxiv.org/abs/1907.07587)**
>
> Scientific computing is increasingly incorporating the advancements in machine learning and the ability to work with large amounts of data. At the same time, machine learning models are becoming increasingly sophisticated and exhibit many features...

and looked at the code of

> **[GitHub - MikeInnes/zygote-paper](https://github.com/MikeInnes/zygote-paper)**
>
> Contribute to MikeInnes/zygote-paper development by creating an account on GitHub.

but it not clear to me how (if) “∂P in practice” is different from Zygote (in its current state).

If the authors have time for a short explanation, it would be nice.
