Skip to content

Some errors from broadcasting #53

Closed
@mcabbott

Description

@mcabbott
julia> gradient(x -> sum(abs2.(x)), [1,2,3.])
([2.0, 4.0, 6.0],)

julia> gradient(x -> sum(x .^ 2), [1,2,3.])
ERROR: MethodError: no method matching (::Diffractor.∂⃖recurse{1})(::typeof(Core._apply_iterate), ::typeof(iterate), ::typeof(Core.apply_type), ::Tuple{DataType, DataType}, ::Core.SimpleVector)

julia> gradient(x -> sum(x .* x'), [1,2,3.])
([12.0, 12.0, 12.0],)

julia> gradient(x -> sum(x ./ x'), [1,2,3.])
ERROR: Rewrite reached intrinsic function bitcast. Missing rule?

The last gives a different error in forward mode, but I'm less sure that I'm doing it right.

Details
julia> using Diffractor: gradient, frule_via_ad, unthunk, DiffractorRuleConfig

julia> gradient(x -> sum(abs2.(x)), [1,2,3.])
([2.0, 4.0, 6.0],)

julia> gradient(x -> sum(x .^ 2), [1,2,3.])
ERROR: MethodError: no method matching (::Diffractor.∂⃖recurse{1})(::typeof(Core._apply_iterate), ::typeof(iterate), ::typeof(Core.apply_type), ::Tuple{DataType, DataType}, ::Core.SimpleVector)
Closest candidates are:
  (::Diffractor.∂⃖recurse)(::Any...) at /Users/me/.julia/dev/Diffractor/src/stage1/generated.jl:408
Stacktrace:
  [1] macro expansion
    @ ~/.julia/dev/Diffractor/src/stage1/generated.jl:0 [inlined]
  [2] (::Diffractor.∂⃖recurse{1})(::typeof(Core._apply_iterate), ::typeof(iterate), ::typeof(Core.apply_type), ::Tuple{DataType, DataType}, ::Core.SimpleVector)
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:417
  [3] (::∂⃖{1})(::typeof(Core._apply_iterate), ::Function, ::Vararg{Any})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:215
  [4] eltypes
    @ ./broadcast.jl:714 [inlined]
  [5] (::Diffractor.∂⃖recurse{1})(::typeof(Base.Broadcast.eltypes), ::Tuple{Base.RefValue{typeof(^)}, Vector{Float64}, Base.RefValue{Val{2}}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:0
  [6] (::∂⃖{1})(f::typeof(Base.Broadcast.eltypes), args::Tuple{Base.RefValue{typeof(^)}, Vector{Float64}, Base.RefValue{Val{2}}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:215
  [7] combine_eltypes
    @ ./broadcast.jl:717 [inlined]
  [8] (::Diffractor.∂⃖recurse{1})(::typeof(Base.Broadcast.combine_eltypes), ::typeof(Base.literal_pow), ::Tuple{Base.RefValue{typeof(^)}, Vector{Float64}, Base.RefValue{Val{2}}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:0
  [9] (::∂⃖{1})(::typeof(Base.Broadcast.combine_eltypes), ::Function, ::Vararg{Any})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:215
 [10] copy
    @ ./broadcast.jl:882 [inlined]
 [11] (::∂⃖{1})(f::typeof(copy), args::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Tuple{Base.OneTo{Int64}}, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Vector{Float64}, Base.RefValue{Val{2}}}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:215
 [12] materialize
    @ ./broadcast.jl:860 [inlined]
 [13] (::∂⃖{1})(f::typeof(Base.Broadcast.materialize), args::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Vector{Float64}, Base.RefValue{Val{2}}}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:215
 [14] #126
    @ ./REPL[100]:1 [inlined]
 [15] (::Diffractor.∂⃖recurse{1})(::var"#126#127", ::Vector{Float64})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:0
 [16] (::∂⃖{1})(f::var"#126#127", args::Vector{Float64})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:215
 [17] ∂⃖(::Function, ::Vararg{Any})
    @ Diffractor ~/.julia/dev/Diffractor/src/interface.jl:25
 [18] (::Diffractor.∇{var"#126#127"})(args::Vector{Float64})
    @ Diffractor ~/.julia/dev/Diffractor/src/interface.jl:121
 [19] Diffractor.(::Function, ::Vector{Float64})
    @ Diffractor ~/.julia/dev/Diffractor/src/interface.jl:128
 [20] top-level scope
    @ REPL[100]:1

julia> gradient(x -> sum(x .* x'), [1,2,3.])
([12.0, 12.0, 12.0],)

julia> gradient(x -> sum(x ./ x'), [1,2,3.])
ERROR: Rewrite reached intrinsic function bitcast. Missing rule?
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:33
  [2] (::∂⃖{1})(::Core.IntrinsicFunction, ::Type, ::Vararg{Any})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:205
  [3] UInt64
    @ ./boot.jl:768 [inlined]
  [4] (::Diffractor.∂⃖recurse{1})(::Type{UInt64}, ::Ptr{Float64})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:0
  [5] (::∂⃖{1})(f::Type{UInt64}, args::Ptr{Float64})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:215
  [6] dataids
    @ ./abstractarray.jl:1457 [inlined]
  [7] (::Diffractor.∂⃖recurse{1})(::typeof(Base.dataids), ::Matrix{Float64})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:0
  [8] (::∂⃖{1})(f::typeof(Base.dataids), args::Matrix{Float64})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:215
  [9] mightalias
    @ ./abstractarray.jl:1433 [inlined]
 [10] ∂⃖
    @ ~/.julia/dev/Diffractor/src/stage1/generated.jl:215 [inlined]
 [11] unalias
    @ ./abstractarray.jl:1398 [inlined]
 [12] ∂⃖
    @ ~/.julia/dev/Diffractor/src/stage1/generated.jl:215 [inlined]
 [13] broadcast_unalias
    @ ./broadcast.jl:934 [inlined]
 [14] ∂⃖
    @ ~/.julia/dev/Diffractor/src/stage1/generated.jl:215 [inlined]
 [15] preprocess
    @ ./broadcast.jl:941 [inlined]
 [16] ∂⃖
    @ ~/.julia/dev/Diffractor/src/stage1/generated.jl:215 [inlined]
 [17] preprocess_args
    @ ./broadcast.jl:943 [inlined]
 [18] ∂⃖
    @ ~/.julia/dev/Diffractor/src/stage1/generated.jl:215 [inlined]
 [19] preprocess
    @ ./broadcast.jl:940 [inlined]
 [20] ∂⃖
    @ ~/.julia/dev/Diffractor/src/stage1/generated.jl:215 [inlined]
 [21] copyto!
    @ ./broadcast.jl:957 [inlined]
 [22] (::Diffractor.∂⃖recurse{1})(::typeof(copyto!), ::Matrix{Float64}, ::Base.Broadcast.Broadcasted{Nothing, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, typeof(/), Tuple{Vector{Float64}, Adjoint{Float64, Vector{Float64}}}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:0
 [23] (::∂⃖{1})(::typeof(copyto!), ::Matrix{Float64}, ::Vararg{Any})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:215
 [24] copyto!
    @ ./broadcast.jl:913 [inlined]
 [25] ∂⃖
    @ ~/.julia/dev/Diffractor/src/stage1/generated.jl:215 [inlined]
 [26] copy
    @ ./broadcast.jl:885 [inlined]
 [27] ∂⃖
    @ ~/.julia/dev/Diffractor/src/stage1/generated.jl:215 [inlined]
 [28] materialize
    @ ./broadcast.jl:860 [inlined]
 [29] (::∂⃖{1})(f::typeof(Base.Broadcast.materialize), args::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{2}, Nothing, typeof(/), Tuple{Vector{Float64}, Adjoint{Float64, Vector{Float64}}}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/generated.jl:215
 [30] #130
    @ ./REPL[102]:1 [inlined]
 [31] ∂⃖
    @ ~/.julia/dev/Diffractor/src/stage1/generated.jl:215 [inlined]
 [32] ∂⃖
    @ ~/.julia/dev/Diffractor/src/interface.jl:25 [inlined]
 [33] (::Diffractor.∇{var"#130#131"})(args::Vector{Float64})
    @ Diffractor ~/.julia/dev/Diffractor/src/interface.jl:121
 [34] Diffractor.(::Function, ::Vector{Float64})
    @ Diffractor ~/.julia/dev/Diffractor/src/interface.jl:128
 [35] top-level scope
    @ REPL[102]:1

julia> using LinearAlgebra

julia> function fjac(f, x)
         delta = Matrix(I, length(x), length(x))
         slice(k) = vec(frule_via_ad(DiffractorRuleConfig(), (0, reshape(delta[:,k], axes(x))), f, x)[2])
         reduce(hcat, [slice(k) for k in LinearIndices(x)])
       end
fjac (generic function with 1 method)

julia> fjac(x -> x .^ 2, [1,2,3.])
3×3 Matrix{Float64}:
 2.0  0.0  0.0
 0.0  4.0  0.0
 0.0  0.0  6.0

julia> fjac(x -> x ./ x', [1,2,3.])
ERROR: MethodError: no method matching unbundle(::Diffractor.CompositeBundle{1, Adjoint{Float64, Vector{Float64}}, Tuple{Diffractor.TangentBundle{1, Vector{Float64}, Tuple{Vector{Bool}}}}})
Closest candidates are:
  unbundle(::Diffractor.TangentBundle{Order, A}) where {Order, Dim, T, A<:AbstractArray{T, Dim}} at /Users/me/.julia/dev/Diffractor/src/tangent.jl:229
  unbundle(::Diffractor.TaylorBundle{Order, A}) where {Order, Dim, T, A<:AbstractArray{T, Dim}} at /Users/me/.julia/dev/Diffractor/src/tangent.jl:247
  unbundle(::Diffractor.UniformBundle{N, A, ZeroTangent}) where {N, T, Dim, A<:AbstractArray{T, Dim}} at /Users/me/.julia/dev/Diffractor/src/tangent.jl:272
Stacktrace:
  [1] (::Diffractor.var"#236#237"{1, ∂☆{1}, Diffractor.CompositeBundle{1, Tuple{Vector{Float64}, Adjoint{Float64, Vector{Float64}}}, Tuple{Diffractor.TangentBundle{1, Vector{Float64}, Tuple{Vector{Bool}}}, Diffractor.CompositeBundle{1, Adjoint{Float64, Vector{Float64}}, Tuple{Diffractor.TangentBundle{1, Vector{Float64}, Tuple{Vector{Bool}}}}}}}})(i::Int64)
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/broadcast.jl:23
  [2] ntuple(f::Diffractor.var"#236#237"{1, ∂☆{1}, Diffractor.CompositeBundle{1, Tuple{Vector{Float64}, Adjoint{Float64, Vector{Float64}}}, Tuple{Diffractor.TangentBundle{1, Vector{Float64}, Tuple{Vector{Bool}}}, Diffractor.CompositeBundle{1, Adjoint{Float64, Vector{Float64}}, Tuple{Diffractor.TangentBundle{1, Vector{Float64}, Tuple{Vector{Bool}}}}}}}}, n::Int64)
    @ Base ./ntuple.jl:19
  [3] (::∂☆{1})(zc::Diffractor.UniformBundle{1, typeof(copy), ZeroTangent}, bc::Diffractor.CompositeBundle{1, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{2}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, typeof(/), Tuple{Vector{Float64}, Adjoint{Float64, Vector{Float64}}}}, Tuple{Diffractor.UniformBundle{1, typeof(/), ZeroTangent}, Diffractor.CompositeBundle{1, Tuple{Vector{Float64}, Adjoint{Float64, Vector{Float64}}}, Tuple{Diffractor.TangentBundle{1, Vector{Float64}, Tuple{Vector{Bool}}}, Diffractor.CompositeBundle{1, Adjoint{Float64, Vector{Float64}}, Tuple{Diffractor.TangentBundle{1, Vector{Float64}, Tuple{Vector{Bool}}}}}}}, Diffractor.CompositeBundle{1, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, Tuple{Diffractor.TangentBundle{1, Base.OneTo{Int64}, Tuple{ChainRulesCore.NoTangent}}, Diffractor.TangentBundle{1, Base.OneTo{Int64}, Tuple{ChainRulesCore.NoTangent}}}}}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/broadcast.jl:16
  [4] ∂☆recurse
    @ ./broadcast.jl:860 [inlined]
  [5] (::Diffractor.∂☆recurse{1})(::Diffractor.UniformBundle{1, typeof(Base.Broadcast.materialize), ZeroTangent}, ::Diffractor.CompositeBundle{1, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{2}, Nothing, typeof(/), Tuple{Vector{Float64}, Adjoint{Float64, Vector{Float64}}}}, Tuple{Diffractor.UniformBundle{1, typeof(/), ZeroTangent}, Diffractor.CompositeBundle{1, Tuple{Vector{Float64}, Adjoint{Float64, Vector{Float64}}}, Tuple{Diffractor.TangentBundle{1, Vector{Float64}, Tuple{Vector{Bool}}}, Diffractor.CompositeBundle{1, Adjoint{Float64, Vector{Float64}}, Tuple{Diffractor.TangentBundle{1, Vector{Float64}, Tuple{Vector{Bool}}}}}}}, Diffractor.UniformBundle{1, Nothing, ZeroTangent}}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/recurse_fwd.jl:0
  [6] (::Diffractor.∂☆internal{1})(::Diffractor.UniformBundle{1, typeof(Base.Broadcast.materialize), ZeroTangent}, ::Vararg{Diffractor.AbstractTangentBundle{1}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/forward.jl:115
  [7] (::∂☆{1})(::Diffractor.UniformBundle{1, typeof(Base.Broadcast.materialize), ZeroTangent}, ::Vararg{Diffractor.AbstractTangentBundle{1}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/forward.jl:140
  [8] ∂☆recurse
    @ ./REPL[104]:1 [inlined]
  [9] (::Diffractor.∂☆recurse{1})(::Diffractor.TangentBundle{1, var"#134#135", Tuple{Int64}}, ::Diffractor.TangentBundle{1, Vector{Float64}, Tuple{Vector{Bool}}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/recurse_fwd.jl:0
 [10] (::Diffractor.∂☆internal{1})(::Diffractor.TangentBundle{1, var"#134#135", Tuple{Int64}}, ::Vararg{Diffractor.AbstractTangentBundle{1}})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/forward.jl:115
 [11] frule_via_ad(::DiffractorRuleConfig, ::Tuple{Int64, Vector{Bool}}, ::Function, ::Vararg{Any})
    @ Diffractor ~/.julia/dev/Diffractor/src/stage1/forward.jl:123
 [12] (::var"#slice#122"{var"#134#135", Vector{Float64}, Matrix{Bool}})(k::Int64)
    @ Main ./REPL[98]:3
 [13] #121
    @ ./none:0 [inlined]
 [14] iterate
    @ ./generator.jl:47 [inlined]
 [15] collect(itr::Base.Generator{LinearIndices{1, Tuple{Base.OneTo{Int64}}}, var"#121#123"{var"#slice#122"{var"#134#135", Vector{Float64}, Matrix{Bool}}}})
    @ Base ./array.jl:774
 [16] fjac(f::Function, x::Vector{Float64})
    @ Main ./REPL[98]:4
 [17] top-level scope
    @ REPL[104]:1

julia> versioninfo()
Julia Version 1.8.0-DEV.502
Commit c4f0d8b2f6 (2021-09-10 16:28 UTC)
Platform Info:
  OS: macOS (arm64-apple-darwin20.6.0)
  CPU: Apple M1
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, cyclone)
Environment:
  JULIA_NUM_THREADS = 4

Edit -- maybe this isn't meant to work? I thought it copied Zygote's unfused rrule(::typeof(broadcasted), f, xs::Numeric...) but in fact I see rules only for a handful of functions, except when there is just one argument.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions