Skip to content

ReverseDiff performance #85

@antoine-levitt

Description

@antoine-levitt

(apologies if this is not the right place for such discussions)

What exactly can we expect of the performance of ReverseDiff? In particular, under what conditions exactly will it produce the gradient of a R^N -> R function in a time comparable to the evaluation of the function (say within a factor of 3-4)?

Below is a function (a simple arithmetic loop over an array), courtesy of @cortner, for which ReverseDiff is consistently ~30 times slower than the function on my machine. Moreoever, the recording and compilation step takes a large amount of time. I thought this was because the FLOPS/byte ratio is too low, as the manual suggests, but increasing it does not change the factor of ~30.

using ReverseDiff: GradientTape, GradientConfig, gradient, gradient!, compile

φ1(r) = r^2 + r^4 + exp(-r)
φ2(r) = -0.1 * r^3

function F(x)
    N = length(x)
    f = φ1(x[2]-x[1])
    for i = 3:N
        f += φ1(x[i]-x[i-1]) + φ2(x[i] - x[i-2])
    end
    return f
end

function benchmark()
    for N in (10000, 20000, 40000)

        # pre-record a GradientTape for `F` using inputs with Float64 elements
        @time const f_tape = GradientTape(F, rand(N))
        # compile `f_tape` into a more optimized representation
        @time const compiled_f_tape = compile(f_tape)
        # some inputs and work buffers to play around with
        gresult = zeros(N)
        x = rand(N)
        println("N = $N")
        println(" > Time for F")
        for n = 1:3
            @time F(x)
        end
        println(" > Time for DF")
        for n = 1:3
            @time gradient!(gresult, compiled_f_tape, x)
        end
    end
end
benchmark()

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