ChainRulesCore.jl icon indicating copy to clipboard operation
ChainRulesCore.jl copied to clipboard

No method matching `(::ChainRulesCore.ProjectTo)(::Tuple{Float64})`

Open Theozeud opened this issue 2 years ago • 9 comments

I get an error that the method:

ERROR: LoadError: MethodError: no method matching (::ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}})(::Tuple{Float64})

is not defined when using Zygote, but I think this should be implemented?

Theozeud avatar Jun 16 '23 09:06 Theozeud

Can you post the whole stacktrace and ideally a MVE? That looks like it is trying to project a Tuple containing 1 Float, down to just one Float which would generally indicate that something has gone wrong somewhere, e.g. an incorrectly defined rule.

You could work around it by defining

(::ProjectTo{Float64})(x::Tuple{Float64}) = only(x) 

But I can't imagine this being a correct situtation that should have arisen without there being a bug somewhere. The message is there to help you

oxinabox avatar Jun 16 '23 15:06 oxinabox

I just had this error in some of my code. Here is an MWE that triggered it

using Zygote

function mwe(x)
    (;dx,) = x
    return sum(Tuple(dx))
end

t(x) = (dx = x,)
l(x) = (mwe∘t)(x)

x = zeros(3)
l(x)

Zygote.gradient(l, x)

I get the following stack trace

ERROR: MethodError: no method matching (::ChainRulesCore.ProjectTo{AbstractArray, NamedTuple{(:element, :axes), Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, Tuple{Base.OneTo{Int64}}}}})(::Tuple{Float64, Float64, Float64})

Closest candidates are:
  (::ChainRulesCore.ProjectTo{AbstractArray})(::Union{LinearAlgebra.Adjoint{T, var"#s971"}, LinearAlgebra.Transpose{T, var"#s971"}} where {T, var"#s971"<:(AbstractVector)})
   @ ChainRulesCore ~/.julia/packages/ChainRulesCore/0t04l/src/projection.jl:247
  (::ChainRulesCore.ProjectTo{AbstractArray})(::AbstractArray{<:ChainRulesCore.AbstractZero})
   @ ChainRulesCore ~/.julia/packages/ChainRulesCore/0t04l/src/projection.jl:244
  (::ChainRulesCore.ProjectTo{AbstractArray})(::AbstractArray{S, M}) where {S, M}
   @ ChainRulesCore ~/.julia/packages/ChainRulesCore/0t04l/src/projection.jl:219
  ...

Stacktrace:
  [1] macro expansion
    @ ~/.julia/packages/ChainRulesCore/0t04l/src/projection.jl:343 [inlined]
  [2] _project_namedtuple(f::NamedTuple{(:dx,), Tuple{ChainRulesCore.ProjectTo{AbstractArray, NamedTuple{(:element, :axes), Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, Tuple{Base.OneTo{Int64}}}}}}}, x::NamedTuple{(:dx,), Tuple{Tuple{Float64, Float64, Float64}}})
    @ ChainRulesCore ~/.julia/packages/ChainRulesCore/0t04l/src/projection.jl:342
  [3] (::ChainRulesCore.ProjectTo{ChainRulesCore.Tangent{NamedTuple{(:dx,), Tuple{Vector{Float64}}}}, NamedTuple{(:dx,), Tuple{ChainRulesCore.ProjectTo{AbstractArray, NamedTuple{(:element, :axes), Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, Tuple{Base.OneTo{Int64}}}}}}}})(dx::NamedTuple{(:dx,), Tuple{Tuple{Float64, Float64, Float64}}})
    @ ChainRulesCore ~/.julia/packages/ChainRulesCore/0t04l/src/projection.jl:335
  [4] (::ChainRulesCore.ProjectTo{ChainRulesCore.Tangent{NamedTuple{(:dx,), Tuple{Vector{Float64}}}}, NamedTuple{(:dx,), Tuple{ChainRulesCore.ProjectTo{AbstractArray, NamedTuple{(:element, :axes), Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, Tuple{Base.OneTo{Int64}}}}}}}})(dx::ChainRulesCore.Tangent{NamedTuple{(:dx,), Tuple{Vector{Float64}}}, NamedTuple{(:dx,), Tuple{Tuple{Float64, Float64, Float64}}}})
    @ ChainRulesCore ~/.julia/packages/ChainRulesCore/0t04l/src/projection.jl:317
  [5] _project
    @ ~/.julia/packages/Zygote/JeHtr/src/compiler/chainrules.jl:189 [inlined]
  [6] (::Zygote.var"#back#298"{:dx, Zygote.Context{false}, NamedTuple{(:dx,), Tuple{Vector{Float64}}}, Vector{Float64}})(Δ::Tuple{Float64, Float64, Float64})
    @ Zygote ~/.julia/packages/Zygote/JeHtr/src/lib/lib.jl:234
  [7] (::Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:dx, Zygote.Context{false}, NamedTuple{(:dx,), Tuple{Vector{Float64}}}, Vector{Float64}}})(Δ::Tuple{Float64, Float64, Float64})
    @ Zygote ~/.julia/packages/ZygoteRules/OgCVT/src/adjoint.jl:71
  [8] Pullback
    @ ~/.julia/packages/ChainRulesCore/0t04l/src/nt_error.jl:5 [inlined]
  [9] (::Zygote.Pullback{Tuple{typeof(mwe), NamedTuple{(:dx,), Tuple{Vector{Float64}}}}, Tuple{Zygote.Pullback{Tuple{Type{Tuple}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{typeof(Base._totuple), Type{Tuple}, Vector{Float64}}, Tuple{Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Int64}, Zygote.var"#2017#back#200"{typeof(identity)}}}}}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:dx, Zygote.Context{false}, NamedTuple{(:dx,), Tuple{Vector{Float64}}}, Vector{Float64}}}, Zygote.ZBack{ChainRules.var"#sum_pullback#1644"{Val{3}, ChainRulesCore.ProjectTo{ChainRulesCore.Tangent{Tuple{Float64, Float64, Float64}}, NamedTuple{(:elements,), Tuple{Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}}}}}}}}})(Δ::Float64)
    @ Zygote ~/.julia/packages/Zygote/JeHtr/src/compiler/interface2.jl:0
 [10] Pullback
    @ ./operators.jl:1034 [inlined]
 [11] Pullback
    @ ./operators.jl:1031 [inlined]
 [12] (::Zygote.Pullback{Tuple{Base.var"##_#97", Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ComposedFunction{typeof(mwe), typeof(t)}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), ComposedFunction{typeof(mwe), typeof(t)}}, Tuple{Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), typeof(t)}, Tuple{Zygote.var"#2017#back#200"{typeof(identity)}, Zygote.Pullback{Tuple{typeof(Base.maybeconstructor), typeof(t)}, Tuple{}}}}, Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), typeof(mwe)}, Tuple{Zygote.var"#2017#back#200"{typeof(identity)}, Zygote.Pullback{Tuple{typeof(Base.maybeconstructor), typeof(mwe)}, Tuple{}}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:outer, Zygote.Context{false}, ComposedFunction{typeof(mwe), typeof(t)}, typeof(mwe)}}, Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Tuple{Nothing}, Tuple{Nothing}}, Zygote.var"#2017#back#200"{typeof(identity)}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:inner, Zygote.Context{false}, ComposedFunction{typeof(mwe), typeof(t)}, typeof(t)}}}}, Zygote.Pullback{Tuple{typeof(Base.call_composed), Tuple{typeof(mwe), typeof(t)}, Tuple{Vector{Float64}}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, Tuple{Zygote.var"#2033#back#209"{Zygote.var"#back#207"{2, 1, Zygote.Context{false}, typeof(mwe)}}, Zygote.var"#2145#back#277"{Zygote.var"#273#276"}, Zygote.Pullback{Tuple{typeof(mwe), NamedTuple{(:dx,), Tuple{Vector{Float64}}}}, Tuple{Zygote.Pullback{Tuple{Type{Tuple}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{typeof(Base._totuple), Type{Tuple}, Vector{Float64}}, Tuple{Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Int64}, Zygote.var"#2017#back#200"{typeof(identity)}}}}}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:dx, Zygote.Context{false}, NamedTuple{(:dx,), Tuple{Vector{Float64}}}, Vector{Float64}}}, Zygote.ZBack{ChainRules.var"#sum_pullback#1644"{Val{3}, ChainRulesCore.ProjectTo{ChainRulesCore.Tangent{Tuple{Float64, Float64, Float64}}, NamedTuple{(:elements,), Tuple{Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}}}}}}}}}, Zygote.Pullback{Tuple{typeof(Base.call_composed), Tuple{typeof(t)}, Tuple{Vector{Float64}}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, Any}}}}})(Δ::Float64)
    @ Zygote ~/.julia/packages/Zygote/JeHtr/src/compiler/interface2.jl:0
 [13] #287
    @ ~/.julia/packages/Zygote/JeHtr/src/lib/lib.jl:206 [inlined]
 [14] #2173#back
    @ ~/.julia/packages/ZygoteRules/OgCVT/src/adjoint.jl:71 [inlined]
 [15] Pullback
    @ ./operators.jl:1031 [inlined]
 [16] (::Zygote.Pullback{Tuple{ComposedFunction{typeof(mwe), typeof(t)}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{Type{NamedTuple}}, Tuple{}}, Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Tuple{Nothing, Nothing}, Tuple{Nothing}}, Zygote.Pullback{Tuple{Base.var"##_#97", Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ComposedFunction{typeof(mwe), typeof(t)}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), ComposedFunction{typeof(mwe), typeof(t)}}, Tuple{Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), typeof(t)}, Tuple{Zygote.var"#2017#back#200"{typeof(identity)}, Zygote.Pullback{Tuple{typeof(Base.maybeconstructor), typeof(t)}, Tuple{}}}}, Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), typeof(mwe)}, Tuple{Zygote.var"#2017#back#200"{typeof(identity)}, Zygote.Pullback{Tuple{typeof(Base.maybeconstructor), typeof(mwe)}, Tuple{}}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:outer, Zygote.Context{false}, ComposedFunction{typeof(mwe), typeof(t)}, typeof(mwe)}}, Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Tuple{Nothing}, Tuple{Nothing}}, Zygote.var"#2017#back#200"{typeof(identity)}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:inner, Zygote.Context{false}, ComposedFunction{typeof(mwe), typeof(t)}, typeof(t)}}}}, Zygote.Pullback{Tuple{typeof(Base.call_composed), Tuple{typeof(mwe), typeof(t)}, Tuple{Vector{Float64}}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, Tuple{Zygote.var"#2033#back#209"{Zygote.var"#back#207"{2, 1, Zygote.Context{false}, typeof(mwe)}}, Zygote.var"#2145#back#277"{Zygote.var"#273#276"}, Zygote.Pullback{Tuple{typeof(mwe), NamedTuple{(:dx,), Tuple{Vector{Float64}}}}, Tuple{Zygote.Pullback{Tuple{Type{Tuple}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{typeof(Base._totuple), Type{Tuple}, Vector{Float64}}, Tuple{Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Int64}, Zygote.var"#2017#back#200"{typeof(identity)}}}}}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:dx, Zygote.Context{false}, NamedTuple{(:dx,), Tuple{Vector{Float64}}}, Vector{Float64}}}, Zygote.ZBack{ChainRules.var"#sum_pullback#1644"{Val{3}, ChainRulesCore.ProjectTo{ChainRulesCore.Tangent{Tuple{Float64, Float64, Float64}}, NamedTuple{(:elements,), Tuple{Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}}}}}}}}}, Zygote.Pullback{Tuple{typeof(Base.call_composed), Tuple{typeof(t)}, Tuple{Vector{Float64}}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, Any}}}}}}}, Zygote.var"#2017#back#200"{typeof(identity)}, Zygote.var"#2370#back#415"{Zygote.var"#pairs_namedtuple_pullback#414"{(), NamedTuple{(), Tuple{}}}}}})(Δ::Float64)
    @ Zygote ~/.julia/packages/Zygote/JeHtr/src/compiler/interface2.jl:0
 [17] Pullback
    @ ~/.julia/packages/ChainRulesCore/0t04l/src/nt_error.jl:9 [inlined]
 [18] (::Zygote.Pullback{Tuple{typeof(l), Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{ComposedFunction{typeof(mwe), typeof(t)}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{Type{NamedTuple}}, Tuple{}}, Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Tuple{Nothing, Nothing}, Tuple{Nothing}}, Zygote.Pullback{Tuple{Base.var"##_#97", Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ComposedFunction{typeof(mwe), typeof(t)}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), ComposedFunction{typeof(mwe), typeof(t)}}, Tuple{Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), typeof(t)}, Tuple{Zygote.var"#2017#back#200"{typeof(identity)}, Zygote.Pullback{Tuple{typeof(Base.maybeconstructor), typeof(t)}, Tuple{}}}}, Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), typeof(mwe)}, Tuple{Zygote.var"#2017#back#200"{typeof(identity)}, Zygote.Pullback{Tuple{typeof(Base.maybeconstructor), typeof(mwe)}, Tuple{}}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:outer, Zygote.Context{false}, ComposedFunction{typeof(mwe), typeof(t)}, typeof(mwe)}}, Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Tuple{Nothing}, Tuple{Nothing}}, Zygote.var"#2017#back#200"{typeof(identity)}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:inner, Zygote.Context{false}, ComposedFunction{typeof(mwe), typeof(t)}, typeof(t)}}}}, Zygote.Pullback{Tuple{typeof(Base.call_composed), Tuple{typeof(mwe), typeof(t)}, Tuple{Vector{Float64}}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, Tuple{Zygote.var"#2033#back#209"{Zygote.var"#back#207"{2, 1, Zygote.Context{false}, typeof(mwe)}}, Zygote.var"#2145#back#277"{Zygote.var"#273#276"}, Zygote.Pullback{Tuple{typeof(mwe), NamedTuple{(:dx,), Tuple{Vector{Float64}}}}, Tuple{Zygote.Pullback{Tuple{Type{Tuple}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{typeof(Base._totuple), Type{Tuple}, Vector{Float64}}, Tuple{Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Int64}, Zygote.var"#2017#back#200"{typeof(identity)}}}}}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:dx, Zygote.Context{false}, NamedTuple{(:dx,), Tuple{Vector{Float64}}}, Vector{Float64}}}, Zygote.ZBack{ChainRules.var"#sum_pullback#1644"{Val{3}, ChainRulesCore.ProjectTo{ChainRulesCore.Tangent{Tuple{Float64, Float64, Float64}}, NamedTuple{(:elements,), Tuple{Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}}}}}}}}}, Zygote.Pullback{Tuple{typeof(Base.call_composed), Tuple{typeof(t)}, Tuple{Vector{Float64}}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, Any}}}}}}}, Zygote.var"#2017#back#200"{typeof(identity)}, Zygote.var"#2370#back#415"{Zygote.var"#pairs_namedtuple_pullback#414"{(), NamedTuple{(), Tuple{}}}}}}, Zygote.Pullback{Tuple{typeof(∘), typeof(mwe), typeof(t)}, Tuple{Zygote.Pullback{Tuple{Type{ComposedFunction}, typeof(mwe), typeof(t)}, Tuple{Zygote.var"#2214#back#309"{Zygote.Jnew{ComposedFunction{typeof(mwe), typeof(t)}, Nothing, false}}, Zygote.Pullback{Tuple{typeof(Core.Typeof), typeof(t)}, Any}, Zygote.Pullback{Tuple{typeof(convert), Type{typeof(t)}, typeof(t)}, Tuple{}}, Zygote.Pullback{Tuple{typeof(Core.Typeof), typeof(mwe)}, Any}, Zygote.Pullback{Tuple{typeof(convert), Type{typeof(mwe)}, typeof(mwe)}, Tuple{}}, Zygote.ZBack{ChainRules.var"#fieldtype_pullback#421"}, Zygote.ZBack{ChainRules.var"#fieldtype_pullback#421"}}}}}}})(Δ::Float64)
    @ Zygote ~/.julia/packages/Zygote/JeHtr/src/compiler/interface2.jl:0
 [19] (::Zygote.var"#75#76"{Zygote.Pullback{Tuple{typeof(l), Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{ComposedFunction{typeof(mwe), typeof(t)}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{Type{NamedTuple}}, Tuple{}}, Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Tuple{Nothing, Nothing}, Tuple{Nothing}}, Zygote.Pullback{Tuple{Base.var"##_#97", Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ComposedFunction{typeof(mwe), typeof(t)}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), ComposedFunction{typeof(mwe), typeof(t)}}, Tuple{Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), typeof(t)}, Tuple{Zygote.var"#2017#back#200"{typeof(identity)}, Zygote.Pullback{Tuple{typeof(Base.maybeconstructor), typeof(t)}, Tuple{}}}}, Zygote.Pullback{Tuple{typeof(Base.unwrap_composed), typeof(mwe)}, Tuple{Zygote.var"#2017#back#200"{typeof(identity)}, Zygote.Pullback{Tuple{typeof(Base.maybeconstructor), typeof(mwe)}, Tuple{}}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:outer, Zygote.Context{false}, ComposedFunction{typeof(mwe), typeof(t)}, typeof(mwe)}}, Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Tuple{Nothing}, Tuple{Nothing}}, Zygote.var"#2017#back#200"{typeof(identity)}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:inner, Zygote.Context{false}, ComposedFunction{typeof(mwe), typeof(t)}, typeof(t)}}}}, Zygote.Pullback{Tuple{typeof(Base.call_composed), Tuple{typeof(mwe), typeof(t)}, Tuple{Vector{Float64}}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, Tuple{Zygote.var"#2033#back#209"{Zygote.var"#back#207"{2, 1, Zygote.Context{false}, typeof(mwe)}}, Zygote.var"#2145#back#277"{Zygote.var"#273#276"}, Zygote.Pullback{Tuple{typeof(mwe), NamedTuple{(:dx,), Tuple{Vector{Float64}}}}, Tuple{Zygote.Pullback{Tuple{Type{Tuple}, Vector{Float64}}, Tuple{Zygote.Pullback{Tuple{typeof(Base._totuple), Type{Tuple}, Vector{Float64}}, Tuple{Zygote.var"#2173#back#289"{Zygote.var"#287#288"{Tuple{Int64}, Zygote.var"#2017#back#200"{typeof(identity)}}}}}}}, Zygote.var"#2184#back#299"{Zygote.var"#back#298"{:dx, Zygote.Context{false}, NamedTuple{(:dx,), Tuple{Vector{Float64}}}, Vector{Float64}}}, Zygote.ZBack{ChainRules.var"#sum_pullback#1644"{Val{3}, ChainRulesCore.ProjectTo{ChainRulesCore.Tangent{Tuple{Float64, Float64, Float64}}, NamedTuple{(:elements,), Tuple{Tuple{ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}, ChainRulesCore.ProjectTo{Float64, NamedTuple{(), Tuple{}}}}}}}}}}}, Zygote.Pullback{Tuple{typeof(Base.call_composed), Tuple{typeof(t)}, Tuple{Vector{Float64}}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, Any}}}}}}}, Zygote.var"#2017#back#200"{typeof(identity)}, Zygote.var"#2370#back#415"{Zygote.var"#pairs_namedtuple_pullback#414"{(), NamedTuple{(), Tuple{}}}}}}, Zygote.Pullback{Tuple{typeof(∘), typeof(mwe), typeof(t)}, Tuple{Zygote.Pullback{Tuple{Type{ComposedFunction}, typeof(mwe), typeof(t)}, Tuple{Zygote.var"#2214#back#309"{Zygote.Jnew{ComposedFunction{typeof(mwe), typeof(t)}, Nothing, false}}, Zygote.Pullback{Tuple{typeof(Core.Typeof), typeof(t)}, Any}, Zygote.Pullback{Tuple{typeof(convert), Type{typeof(t)}, typeof(t)}, Tuple{}}, Zygote.Pullback{Tuple{typeof(Core.Typeof), typeof(mwe)}, Any}, Zygote.Pullback{Tuple{typeof(convert), Type{typeof(mwe)}, typeof(mwe)}, Tuple{}}, Zygote.ZBack{ChainRules.var"#fieldtype_pullback#421"}, Zygote.ZBack{ChainRules.var"#fieldtype_pullback#421"}}}}}}}})(Δ::Float64)
    @ Zygote ~/.julia/packages/Zygote/JeHtr/src/compiler/interface.jl:45
 [20] gradient(f::Function, args::Vector{Float64})
    @ Zygote ~/.julia/packages/Zygote/JeHtr/src/compiler/interface.jl:97
 [21] top-level scope
    @ ~/.julia/packages/ChainRulesCore/0t04l/src/nt_error.jl:14

And my environment is

Status `/tmp/jl_P6LJVc/Project.toml`
  [e88e6eb3] Zygote v0.6.62
Julia Version 1.9.1
Commit 147bdf428cd (2023-06-07 08:27 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 20 × 12th Gen Intel(R) Core(TM) i7-12700H
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-14.0.6 (ORCJIT, alderlake)
  Threads: 1 on 20 virtual cores
Environment:
  JULIA_EDITOR = code
  JULIA_NUM_THREADS = 1

ptiede avatar Jul 11 '23 07:07 ptiede

in that MWE the function t is not defined. So I can't run this

oxinabox avatar Jul 11 '23 09:07 oxinabox

Sorry, that's embarrassing. Updated the example it should work now.

ptiede avatar Jul 11 '23 10:07 ptiede

Note that unlike the original issue, this one is ProjectTo{AbstractArray}(:: Tuple{Float64, Float64, Float64}) i.e. it's about NTuple-vs-Array, not 1-Tuple-vs-Number.

I think this is part of it:

julia> gradient(x -> sum(Tuple(Zygote.@showgrad x)), [2.2, 3.3])
∂(x) = (1.0, 1.0)  # a Tuple not a Vector
([1.0, 1.0],)  # final answer fixed by _project

julia> pullback(x -> sum(Tuple(x)), [2.2, 3.3])[2](1.0)  # avoids final _project
((1.0, 1.0),)

julia> using ChainRules, ChainRulesCore

julia> rrule(Tuple, [2.2, 3.3])  # there is no rrule for this

julia> rrule(sum, (2.2, 3.3))
(5.5, ChainRules.var"#sum_pullback#1644"{Val{2}, ProjectTo{Tangent{Tuple{Float64, Float64}}, ...

Adding some printing, there are also nothings which don't seem to be coming from that:

julia> function mwe(x)
           Zygote.@showgrad @show x
           (;dx,) = x
           Zygote.@showgrad @show dx
           t = Tuple(dx)
           Zygote.@showgrad @show t
           sum(t)
       end
mwe (generic function with 1 method)

julia> x = [2.2, 3.3];

julia> l(x)
x = (dx = [2.2, 3.3],)
dx = [2.2, 3.3]
t = (2.2, 3.3)
5.5

julia> gradient(l, x)
x = (dx = [2.2, 3.3],)
dx = [2.2, 3.3]
t = (2.2, 3.3)
∂(#= REPL[8]:6 =# @show t) = nothing
∂(#= REPL[8]:4 =# @show dx) = nothing
ERROR: MethodError: no method matching (::ChainRulesCore.ProjectTo{AbstractArray, @NamedTuple{element::ChainRulesCore.ProjectTo{Float64, @NamedTuple{}}, axes::Tuple{Base.OneTo{Int64}}}})(::Tuple{Float64, Float64})

julia> ForwardDiff.gradient(l, x)
x = (dx = ForwardDiff.Dual{ForwardDiff.Tag{typeof(l), Float64}, Float64, 2}[Dual{ForwardDiff.Tag{typeof(l), Float64}}(2.2,1.0,0.0), Dual{ForwardDiff.Tag{typeof(l), Float64}}(3.3,0.0,1.0)],)
dx = ForwardDiff.Dual{ForwardDiff.Tag{typeof(l), Float64}, Float64, 2}[Dual{ForwardDiff.Tag{typeof(l), Float64}}(2.2,1.0,0.0), Dual{ForwardDiff.Tag{typeof(l), Float64}}(3.3,0.0,1.0)]
t = (Dual{ForwardDiff.Tag{typeof(l), Float64}}(2.2,1.0,0.0), Dual{ForwardDiff.Tag{typeof(l), Float64}}(3.3,0.0,1.0))
2-element Vector{Float64}:
 1.0
 1.0

mcabbott avatar Jul 11 '23 13:07 mcabbott

Ah ok, should I open up a new issue to track this?

ptiede avatar Jul 14 '23 22:07 ptiede

Maybe a Zygote issue? The gradient of Tuple(::Vector) seems to be giving the wrong type.

mcabbott avatar Jul 15 '23 02:07 mcabbott

Opened an issue https://github.com/FluxML/Zygote.jl/issues/1443

ptiede avatar Jul 29 '23 14:07 ptiede

Adding some printing, there are also nothings which don't seem to be coming from that:

I think those come from trying to use @showgrad in statement position. it only works when the result of the wrapped expression is used in a path that contributes to the gradient, unfortunately.

ToucheSir avatar Aug 09 '23 03:08 ToucheSir