# My gradients IdDIct keys are GlobalRefs instead of arrays

**URL:** <https://discourse.julialang.org/t/my-gradients-iddict-keys-are-globalrefs-instead-of-arrays/69665>\
**Category:** Machine Learning\
**Tags:** question, flux\
**Created:** [October 13, 2021, 8:11am UTC](https://discourse.julialang.org/t/my-gradients-iddict-keys-are-globalrefs-instead-of-arrays/69665 "2021-10-13T08:11:39Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Johan-Gronqvist](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johan-gronqvist/32/29895_2.png) [@Johan-Gronqvist](https://discourse.julialang.org/u/Johan-Gronqvist)\
**Post date:** [October 13, 2021, 8:11am UTC](https://discourse.julialang.org/t/my-gradients-iddict-keys-are-globalrefs-instead-of-arrays/69665/1 "2021-10-13T08:11:39Z")

</div>

My gradients sometimes appear with keys of type `GlobalRef`. I do not understand why and I do not understand how to change that.

Example code:

```julia
using Flux

function h(x; bs=bs)
    for b in bs[1:end-1]
        x = x+b
    end
    x = x+bs[end]
    only(x)
end

bs = [[0.0], [1.0], [2.0] ]
grads = gradient(() -> h(x, bs=bs), params(bs))
@show grads[bs[1]]
@show grads[bs[2]]
@show grads[bs[3]]
for (k, v) in grads.grads
    if k isa GlobalRef
        @show k
        @show v
    end
end

```

The output shows that the `grads.grads` `IdDict` contains the expected gradients for `b[1]` and `b[2]` indexed by the “arrays” (I am not sure what the terminology is), but that it contains `nothing` for `b[3]`. The same `IdDict` does, however, contain one key which is a `GlobalRef` to `:(Main.bs)`, and there is contains `nothing` for the first two elements, but the expected gradient for the last element.

1. What should this function look like to give me the expected gradient as `grads[bs[3]]`?
2. What determines if the gradient appears with a `GlobalRef` or array as its key in the `IdDict`, and what do I need to understand to avoid this problem in the future?

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [October 13, 2021, 8:16am UTC](https://discourse.julialang.org/t/my-gradients-iddict-keys-are-globalrefs-instead-of-arrays/69665/2 "2021-10-13T08:16:27Z")

</div>

This feels like a bug in Zygote.  
I have never seen this occur before.

Maybe open an issue on the Zygote.jl repo

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [October 17, 2021, 5:50pm UTC](https://discourse.julialang.org/t/my-gradients-iddict-keys-are-globalrefs-instead-of-arrays/69665/3 "2021-10-17T17:50:11Z")

</div>

`GlobalRefs` have been a feature of implicit params for some time now. AIUI Zygote needs them and there was a plan to expose them for updating global variables, but that plan was canned. Usually you don’t see them because `Zygote.Grads` ignores them when iterating, but everything is retained in the underlying IdDict.

Back to the problem at hand, since only parameter is being used here, it makes sense to use explicit instead of implicit gradients. This will capture each element of `bs`:

```julia
julia> grads = only(gradient(bs -> h(x, bs=bs), bs))
3-element Vector{Zygote.OneElement{Float64, 1, Tuple{Int64}, Tuple{Base.OneTo{Int64}}}}:
 [1.0]
 [1.0]
 [1.0]

julia> map(collect, grads) # just for the nicer show
3-element Vector{Vector{Float64}}:
 [1.0]
 [1.0]
 [1.0]

```
