I will probably have to create a MWE, which I am loathe to do because of the multiple interacting pieces. But here is an error occurring in Zygote, probably due to some kind of array content corruption. I ran with --inline=no and --bound-check=yes, and found that there was still inlining performed. Strange. I also tried with --optimization=0.
Here is the error, in case something jumps out:
ERROR: UndefVarError: π³ not defined
Stacktrace:
[1] βππΈπ!
@ ~/.julia/packages/Tullio/NGyNM/src/macro.jl:1211 [inlined]
[2] tile_halves(fun!::var"#βππΈπ!#15", ::Type{Union{Nothing, Vector{Any}}}, As::Tuple{Vector{Float64}, Nothing, Nothing, Nothing, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Tuple{Int64, Int64}}, Vector{Float64}}, Is::Tuple{}, Js::Tuple{UnitRange{Int64}, UnitRange{Int64}}, keep::Nothing, final::Nothing)
@ Tullio ~/.julia/packages/Tullio/NGyNM/src/threads.jl:139
[3] tile_halves(fun!::var"#βππΈπ!#15", ::Type{Union{Nothing, Vector{Any}}}, As::Tuple{Vector{Float64}, Nothing, Nothing, Nothing, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Tuple{Int64, Int64}}, Vector{Float64}}, Is::Tuple{}, Js::Tuple{UnitRange{Int64}, UnitRange{Int64}}, keep::Nothing, final::Nothing) (repeats 2 times)
@ Tullio ~/.julia/packages/Tullio/NGyNM/src/threads.jl:146
[4] tile_halves
@ ~/.julia/packages/Tullio/NGyNM/src/threads.jl:136 [inlined]
[5] βthreader(fun!::var"#βππΈπ!#15", #unused#::Type{Union{Nothing, Vector{Any}}}, As::Tuple{Vector{Float64}, Nothing, Nothing, Nothing, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Tuple{Int64, Int64}}, Vector{Float64}}, I0s::Tuple{}, J0s::Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, block::Int64)
@ Tullio ~/.julia/packages/Tullio/NGyNM/src/threads.jl:103
[6] (::var"#17#ββ³πΆπβ―#16"{var"#βππΈπ!#15"})(π₯β::Vector{Float64}, β::Vector{Float64}, coef::Vector{Float64}, x::Vector{Float64}, I::Vector{Tuple{Int64, Int64}}, y::Vector{Float64})
@ Main ~/.julia/packages/Tullio/NGyNM/src/macro.jl:1300
[7] tullio_back
@ ~/.julia/packages/Tullio/NGyNM/src/eval.jl:53 [inlined]
[8] (::Zygote.ZBack{Tullio.var"#tullio_back#156"{Tullio.Eval{var"#β³πΆπβ―#17"{var"#ππΈπ!#14"}, var"#17#ββ³πΆπβ―#16"{var"#βππΈπ!#15"}}, Tuple{Vector{Float64}, Vector{Float64}, Vector{Tuple{Int64, Int64}}, Vector{Float64}}, Vector{Float64}}})(dy::Vector{Float64})
@ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/chainrules.jl:206
[9] Pullback
@ ~/src/2022/basic_UODE/custom_lux_layer/Polynomial.jl:25 [inlined]
[10] (::typeof(β(Ξ»)))(Ξ::Vector{Float64})
@ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface2.jl:0
[11] Pullback
@ ~/src/2022/basic_UODE/custom_lux_layer/Polynomial_layer.jl:53 [inlined]
[12] (::typeof(β(Ξ»)))(Ξ::Tuple{Vector{Float64}, Vector{Float64}, Nothing})
@ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface2.jl:0
[13] Pullback
@ ~/src/2022/basic_UODE/custom_lux_layer/testing_lux_layer_test.jl:78 [inlined]
[14] Pullback
@ ~/src/2022/basic_UODE/custom_lux_layer/testing_lux_layer_test.jl:132 [inlined]
[15] (::typeof(β(Ξ»)))(Ξ::Float64)
@ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface2.jl:0
[16] (::Zygote.var"#60#61"{typeof(β(Ξ»))})(Ξ::Float64)
@ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface.jl:45
[17] gradient(f::Function, args::ComponentVector{Float32, Vector{Float32}, Tuple{Axis{(coeffs = ViewAxis(1:30, ShapedAxis((2, 15), NamedTuple())),)}}})
@ Zygote ~/.julia/packages/Zygote/SmJK6/src/compiler/interface.jl:97
[18] main(tstate::Lux.Training.TrainState{NamedTuple{(:coeffs,), Tuple{Matrix{Float32}}}, NamedTuple{(), Tuple{}}, NamedTuple{(:coeffs,), Tuple{Optimisers.Leaf{Adam{Float32}, Tuple{Matrix{Float32}, Matrix{Float32}, Tuple{Float32, Float32}}}}}, Polylayer{typeof(Lux.rand32)}}, vjp::Lux.Training.ZygoteVJP, data::Tuple{Matrix{Float32}, Matrix{Float64}}, epochs::Int64)
@ Main ~/src/2022/basic_UODE/custom_lux_layer/testing_lux_layer_test.jl:132
[19] top-level scope
@ ~/src/2022/basic_UODE/custom_lux_layer/testing_lux_layer_test.jl:156
I was able to resolve the mutation issue (which I still do not understand), via:
Ix = 0:degree
Jx = 0:degree
#I = [(x=i,y=j) for i in Ix for j in Jx if i+j <= degree]
I = [(i,j) for i in Ix for j in Jx if i+j <= degree]
coef = randn(length(I))
println("=====> Polynomial, length coef: ", length(coef))
Poly(coef) = @tullio poly[i] := coef[j] * x[i]^I[j][1] * y[i]^I[j][2] grad=Dual nograd=x nograd=y nograd=I
I still do not understand why the nograd=I was not respected. I probably misunderstand something.
Thanks,