Hello, I am new to Julia (although not really to programming) and not a top-brain in calculus or statistical learning - although I think I have enough background to understand complex stuff if I put a bit of time I was evaluating which kind of code complexity I can use with Zygote.
I wrote this snippet:
using Zygote
@enum TaskType TaskA=1 TaskB
function process_items(cost_per_item::Int64, items_per_tick::Int64, items::Array{TaskType, 1})
processing::Array{Int64,1} = Int64[]
for i in items
cost = cost_per_item
if i == TaskB
cost = cost_per_item * 2
end
push!(processing, cost)
end
to_process::Int64 = size(processing)[1]
ticks::Int64 = 0
while to_process > 0
processed_this_tick::Int64 = 0
next::Int64 = 1
while processed_this_tick < items_per_tick && (next <= size(processing)[1])
processing[next] -= 1
if processing[next] <= 0
deleteat!(processing, next)
else
next += 1
end
processed_this_tick += 1
end
ticks += 1
to_process = size(processing)[1]
end
return ticks
end
cpi = 2
ipt = 4
g = gradient(
(cost_per_item, item_per_tick) -> process_items(cost_per_item, item_per_tick, [TaskA, TaskA, TaskA, TaskA, TaskA, TaskA, TaskA, TaskA])
, cpi, ipt)
println(g)
My idea was to get gradients for (cost_per_item, item_per_tick) while calling the function on some known “Tasks”, and the idea is then to write an “optimizer” that could find the optimal values for those items given the Tasks via eg. backpropagation.
If I try to run the code, I get:
ERROR: LoadError: Can't differentiate foreigncall expression
Stacktrace:
[1] error(s::String)
@ Base .\error.jl:33
[2] Pullback
@ .\array.jl:895 [inlined]
[3] (::typeof(∂(_deleteat!)))(Δ::Nothing)
@ Zygote C:\Users\Rudi\.julia\packages\Zygote\nsu1Y\src\compiler\interface2.jl:0
[4] Pullback
@ .\array.jl:1339 [inlined]
[5] (::typeof(∂(deleteat!)))(Δ::Nothing)
@ Zygote C:\Users\Rudi\.julia\packages\Zygote\nsu1Y\src\compiler\interface2.jl:0
[6] Pullback
@ C:\Users\Rudi\Documents\myprojects\julia_experiments\micro_processor.jl:23 [inlined]
[7] (::typeof(∂(process_items)))(Δ::Int64)
@ Zygote C:\Users\Rudi\.julia\packages\Zygote\nsu1Y\src\compiler\interface2.jl:0
[8] Pullback
@ C:\Users\Rudi\Documents\myprojects\julia_experiments\micro_processor.jl:51 [inlined]
[9] (::typeof(∂(#1)))(Δ::Int64)
@ Zygote C:\Users\Rudi\.julia\packages\Zygote\nsu1Y\src\compiler\interface2.jl:0
[10] (::Zygote.var"#50#51"{typeof(∂(#1))})(Δ::Int64)
@ Zygote C:\Users\Rudi\.julia\packages\Zygote\nsu1Y\src\compiler\interface.jl:41
[11] gradient(::Function, ::Int64, ::Vararg{Int64, N} where N)
@ Zygote C:\Users\Rudi\.julia\packages\Zygote\nsu1Y\src\compiler\interface.jl:76
[12] top-level scope
@ C:\Users\Rudi\Documents\myprojects\julia_experiments\micro_processor.jl:50
in expression starting at C:\Users\Rudi\Documents\myprojects\julia_experiments\micro_processor.jl:50
Now, somehow I seem to understand I can’t use “deleteat!”, which might even be understandable, since it has side-effects-oh-my etc. However, I was wondering:
- Is “deleteat” really not expected to work with Zygote?
- What are the things I should be careful with when writing code I want to differentiate, eg, which constructs or functions should I avoid? Like, “push!” seems to be ok in this case, is it?
- Maybe difficult question, however: is what I am trying to do (getting gradients only for those 2 variables, then try to back-propagate) something that I should be able to accomplish?
Thanks everybody in advance!