Closed
Description
Hi, and thanks for this amazing interface!
When computing jacobians, I recently noted a significant speed difference between standalone Zygote and Zygote used as an AD backend. The allocations also differ wildly. Do you happen to know where that comes from?
Here's a minimal working example:
julia> using AbstractDifferentiation, BenchmarkTools, Zygote
julia> f(x) = x .^ 2
f (generic function with 1 method)
julia> x = rand(100);
julia> ab = AD.ZygoteBackend()
AbstractDifferentiation.ReverseRuleConfigBackend{Zygote.ZygoteRuleConfig{Zygote.Context}}(Zygote.ZygoteRuleConfig{Zygote.Context}(Zygote.Context(nothing)))
julia> Zygote.jacobian(f, x)
([1.3044988022198039 0.0 … 0.0 0.0; 0.0 1.9710054432976252 … 0.0 0.0; … ; 0.0 0.0 … 1.9276513864536091 0.0; 0.0 0.0 … 0.0 1.6930015760093526],)
julia> AD.jacobian(ab, f, x)
([1.3044988022198039 0.0 … 0.0 0.0; 0.0 1.9710054432976252 … 0.0 0.0; … ; 0.0 0.0 … 1.9276513864536091 0.0; 0.0 0.0 … 0.0 1.6930015760093526],)
julia> @benchmark Zygote.jacobian(f, x)
BenchmarkTools.Trial: 7001 samples with 1 evaluation.
Range (min … max): 629.524 μs … 5.403 ms ┊ GC (min … max): 0.00% … 87.03%
Time (median): 681.270 μs ┊ GC (median): 0.00%
Time (mean ± σ): 712.290 μs ± 295.183 μs ┊ GC (mean ± σ): 3.42% ± 6.90%
▃█▄
▁▁▁▁▁▁▂▁▁▁▁▂▂▂▂▁▁▃███▇▄▄▃▅▅▅▄▄▃▃▃▃▂▂▂▂▂▂▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▂
630 μs Histogram: frequency by time 778 μs <
Memory estimate: 427.06 KiB, allocs estimate: 4141.
julia> @benchmark AD.jacobian(ab, f, x)
BenchmarkTools.Trial: 1393 samples with 1 evaluation.
Range (min … max): 2.673 ms … 64.564 ms ┊ GC (min … max): 0.00% … 94.96%
Time (median): 2.999 ms ┊ GC (median): 0.00%
Time (mean ± σ): 3.583 ms ± 4.786 ms ┊ GC (mean ± σ): 11.42% ± 8.30%
▂▇██▆▆▅▄▃▂
█████████████▆▇█▆▅▅▅▅▅▅▅▅▄▅▁▆▁▁▁▁▄▄▁▄▁▄▁▅▄▄▁▁▁▄▁▅▄▄▁▁▁▁▄▄▄ █
2.67 ms Histogram: log(frequency) by time 8.1 ms <
Memory estimate: 1.26 MiB, allocs estimate: 28023.