From 5b532c46a1c873f22610382ee6174fb20ceb5705 Mon Sep 17 00:00:00 2001 From: Guillaume Dalle <22795598+gdalle@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:14:47 +0200 Subject: [PATCH 1/5] Shorter sparse AD tests --- .../src/scenarios/sparse.jl | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/DifferentiationInterfaceTest/src/scenarios/sparse.jl b/DifferentiationInterfaceTest/src/scenarios/sparse.jl index b0a7c5aa4..7d3cc8961 100644 --- a/DifferentiationInterfaceTest/src/scenarios/sparse.jl +++ b/DifferentiationInterfaceTest/src/scenarios/sparse.jl @@ -214,9 +214,10 @@ end ## Various matrices -function banded_matrix(m, n, b) - pairs = [k => rand(min(m, n) - k) for k in 0:b] - return spdiagm(m, n, pairs...) +function banded_matrix(::Type{T}, n, b) where {T} + @assert b <= n + pairs = [k => rand(T, n - k) for k in 0:b] + return spdiagm(n, n, pairs...) end ### Linear map @@ -245,7 +246,7 @@ end function squarelinearmap_scenarios(x::AbstractVector, band_sizes) n = length(x) scens = Scenario[] - for A in vcat(banded_matrix.(2n, n, band_sizes), banded_matrix.(n รท 2, n, band_sizes)) + for A in banded_matrix.(eltype(x), n, band_sizes) f = SquareLinearMap(A) f! = f y = f(x) @@ -305,7 +306,7 @@ end function squarequadraticform_scenarios(x::AbstractVector, band_sizes) n = length(x) scens = Scenario[] - for A in banded_matrix.(n, n, band_sizes) + for A in banded_matrix.(eltype(x), n, band_sizes) f = SquareQuadraticForm(A) grad = squarequadraticform_gradient(x, A) hess = sparse(squarequadraticform_hessian(x, A)) @@ -324,7 +325,7 @@ end Create a vector of [`Scenario`](@ref)s with sparse array types, focused on sparse Jacobians and Hessians. """ function sparse_scenarios( - rng::AbstractRNG=default_rng(); band_sizes=0:4:36, include_constantified=false + rng::AbstractRNG=default_rng(); band_sizes=[5, 10, 20], include_constantified=false ) scens = vcat( sparse_vec_to_vec_scenarios(rand(rng, 6)), @@ -335,8 +336,8 @@ function sparse_scenarios( sparse_mat_to_num_scenarios(rand(rng, 2, 3)), ) if !isempty(band_sizes) - append!(scens, squarelinearmap_scenarios(rand(rng, 100), band_sizes)) - append!(scens, squarequadraticform_scenarios(rand(rng, 100), band_sizes)) + append!(scens, squarelinearmap_scenarios(rand(rng, 50), band_sizes)) + append!(scens, squarequadraticform_scenarios(rand(rng, 50), band_sizes)) end include_constantified && append!(scens, constantify(scens)) return scens From 02216a520bb49fe5cc61638231b3f220c97807e0 Mon Sep 17 00:00:00 2001 From: Guillaume Dalle <22795598+gdalle@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:16:52 +0200 Subject: [PATCH 2/5] Make test sets verbose at file level --- DifferentiationInterface/test/runtests.jl | 8 ++++++-- DifferentiationInterfaceTest/test/runtests.jl | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/DifferentiationInterface/test/runtests.jl b/DifferentiationInterface/test/runtests.jl index 51d370012..a1758105b 100644 --- a/DifferentiationInterface/test/runtests.jl +++ b/DifferentiationInterface/test/runtests.jl @@ -28,7 +28,9 @@ GROUP = get(ENV, "JULIA_DI_TEST_GROUP", "All") isdir(joinpath(@__DIR__, category)) || continue @testset verbose = true for folder in readdir(joinpath(@__DIR__, category)) isdir(joinpath(@__DIR__, category, folder)) || continue - @testset "$file" for file in readdir(joinpath(@__DIR__, category, folder)) + @testset verbose = true "$file" for file in readdir( + joinpath(@__DIR__, category, folder) + ) endswith(file, ".jl") || continue @info "Testing $category/$folder/$file" include(joinpath(@__DIR__, category, folder, file)) @@ -39,7 +41,9 @@ GROUP = get(ENV, "JULIA_DI_TEST_GROUP", "All") category, folder = split(GROUP, '/') @testset verbose = true "$category" begin @testset verbose = true "$folder" begin - @testset "$file" for file in readdir(joinpath(@__DIR__, category, folder)) + @testset verbose = true "$file" for file in readdir( + joinpath(@__DIR__, category, folder) + ) endswith(file, ".jl") || continue @info "Testing $category/$folder/$file" include(joinpath(@__DIR__, category, folder, file)) diff --git a/DifferentiationInterfaceTest/test/runtests.jl b/DifferentiationInterfaceTest/test/runtests.jl index 8bc6914e0..79a0ae019 100644 --- a/DifferentiationInterfaceTest/test/runtests.jl +++ b/DifferentiationInterfaceTest/test/runtests.jl @@ -17,19 +17,19 @@ GROUP = get(ENV, "JULIA_DIT_TEST_GROUP", "All") end if GROUP == "Zero" || GROUP == "All" - @testset verbose = false "Zero" begin + @testset verbose = true "Zero" begin include("zero_backends.jl") end end if GROUP == "Standard" || GROUP == "All" - @testset verbose = false "Standard" begin + @testset verbose = true "Standard" begin include("standard.jl") end end if GROUP == "Weird" || GROUP == "All" - @testset verbose = false "Weird" begin + @testset verbose = true "Weird" begin include("weird.jl") end end From dee6cbabfbe77d216c622478370a7f8014f588dd Mon Sep 17 00:00:00 2001 From: Guillaume Dalle <22795598+gdalle@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:01:32 +0200 Subject: [PATCH 3/5] Benchmark allocations on StaticArrays --- .../test/Back/ForwardDiff/test.jl | 17 ++++++++++ ...erentiationInterfaceTestStaticArraysExt.jl | 33 ++----------------- .../src/scenarios/default.jl | 4 +-- 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/DifferentiationInterface/test/Back/ForwardDiff/test.jl b/DifferentiationInterface/test/Back/ForwardDiff/test.jl index f84666f44..31229c38a 100644 --- a/DifferentiationInterface/test/Back/ForwardDiff/test.jl +++ b/DifferentiationInterface/test/Back/ForwardDiff/test.jl @@ -3,6 +3,7 @@ Pkg.add("ForwardDiff") using ComponentArrays: ComponentArrays using DifferentiationInterface, DifferentiationInterfaceTest +import DifferentiationInterfaceTest as DIT using ForwardDiff: ForwardDiff using StaticArrays: StaticArrays using Test @@ -57,3 +58,19 @@ test_differentiation( ## Static test_differentiation(AutoForwardDiff(), static_scenarios(); logging=LOGGING) + +@testset verbose = true "No allocations on StaticArrays" begin + filtered_static_scenarios = filter(static_scenarios(; include_batchified=false)) do scen + DIT.function_place(scen) == :out && DIT.operator_place(scen) == :out + end + data = benchmark_differentiation( + AutoForwardDiff(), + filtered_static_scenarios; + benchmark=:prepared, + excluded=vcat(SECOND_ORDER, :pullback, :pushforward), # TODO: figure this out + logging=LOGGING, + ) + @testset "$(row[:scenario])" for row in eachrow(data) + @test row[:allocs] == 0 + end +end; diff --git a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestStaticArraysExt/DifferentiationInterfaceTestStaticArraysExt.jl b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestStaticArraysExt/DifferentiationInterfaceTestStaticArraysExt.jl index 0e7f02d4b..dcd14b4cf 100644 --- a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestStaticArraysExt/DifferentiationInterfaceTestStaticArraysExt.jl +++ b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestStaticArraysExt/DifferentiationInterfaceTestStaticArraysExt.jl @@ -8,19 +8,10 @@ using SparseArrays: SparseArrays, SparseMatrixCSC, nnz, spdiagm using StaticArrays: MArray, MMatrix, MVector, SArray, SMatrix, SVector mySArray(f::Function) = f -myMArray(f::Function) = f - -mySArray(::DIT.NumToArr{A}) where {T,A<:AbstractVector{T}} = DIT.NumToArr(SVector{6,T}) -myMArray(::DIT.NumToArr{A}) where {T,A<:AbstractVector{T}} = DIT.NumToArr(MVector{6,T}) - -mySArray(::DIT.NumToArr{A}) where {T,A<:AbstractMatrix{T}} = DIT.NumToArr(SMatrix{2,3,T,6}) -myMArray(::DIT.NumToArr{A}) where {T,A<:AbstractMatrix{T}} = DIT.NumToArr(MMatrix{2,3,T,6}) - mySArray(f::DIT.MultiplyByConstant) = f -myMArray(f::DIT.MultiplyByConstant) = f - mySArray(f::DIT.WritableClosure) = f -myMArray(f::DIT.WritableClosure) = f +mySArray(::DIT.NumToArr{A}) where {T,A<:AbstractVector{T}} = DIT.NumToArr(SVector{6,T}) +mySArray(::DIT.NumToArr{A}) where {T,A<:AbstractMatrix{T}} = DIT.NumToArr(SMatrix{2,3,T,6}) mySArray(x::Number) = x myMArray(x::Number) = x @@ -36,13 +27,8 @@ function myMArray(x::AbstractMatrix{T}) where {T} end mySArray(x::Tuple) = map(mySArray, x) -myMArray(x::Tuple) = map(myMArray, x) - mySArray(x::DI.Constant) = DI.Constant(mySArray(DI.unwrap(x))) -myMArray(x::DI.Constant) = DI.Constant(myMArray(DI.unwrap(x))) - mySArray(::Nothing) = nothing -myMArray(::Nothing) = nothing function mySArray(scen::Scenario{op,pl_op,pl_fun}) where {op,pl_op,pl_fun} (; f, x, y, tang, contexts, res1, res2) = scen @@ -57,22 +43,9 @@ function mySArray(scen::Scenario{op,pl_op,pl_fun}) where {op,pl_op,pl_fun} ) end -function myMArray(scen::Scenario{op,pl_op,pl_fun}) where {op,pl_op,pl_fun} - (; f, x, y, tang, contexts, res1, res2) = scen - return Scenario{op,pl_op,pl_fun}( - myMArray(f); - x=myMArray(x), - y=pl_fun == :in ? myMArray(y) : myMArray(y), - tang=myMArray(tang), - contexts=myMArray(contexts), - res1=myMArray(res1), - res2=myMArray(res2), - ) -end - function DIT.static_scenarios(args...; kwargs...) scens = DIT.default_scenarios(args...; kwargs...) - return vcat(mySArray.(scens), myMArray.(scens)) + return mySArray.(scens) end end diff --git a/DifferentiationInterfaceTest/src/scenarios/default.jl b/DifferentiationInterfaceTest/src/scenarios/default.jl index 74506155e..1803df72e 100644 --- a/DifferentiationInterfaceTest/src/scenarios/default.jl +++ b/DifferentiationInterfaceTest/src/scenarios/default.jl @@ -71,8 +71,8 @@ end ## Number to array -multiplicator(::Type{A}) where {A<:AbstractVector} = convert(A, float.(1:6)) -multiplicator(::Type{A}) where {A<:AbstractMatrix} = convert(A, reshape(float.(1:6), 2, 3)) +multiplicator(::Type{A}) where {A<:AbstractVector} = convert(A, 1:6) +multiplicator(::Type{A}) where {A<:AbstractMatrix} = convert(A, reshape(1:6, 2, 3)) struct NumToArr{A} end NumToArr(::Type{A}) where {A} = NumToArr{A}() From ef55550cedfe5714d94f1ca5721a27d232bc77b4 Mon Sep 17 00:00:00 2001 From: Guillaume Dalle <22795598+gdalle@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:09:34 +0200 Subject: [PATCH 4/5] Fix pushforward --- .../ext/DifferentiationInterfaceForwardDiffExt/onearg.jl | 5 +++-- DifferentiationInterface/test/Back/ForwardDiff/test.jl | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/DifferentiationInterface/ext/DifferentiationInterfaceForwardDiffExt/onearg.jl b/DifferentiationInterface/ext/DifferentiationInterfaceForwardDiffExt/onearg.jl index 3bf9211e6..0e476c55a 100644 --- a/DifferentiationInterface/ext/DifferentiationInterfaceForwardDiffExt/onearg.jl +++ b/DifferentiationInterface/ext/DifferentiationInterfaceForwardDiffExt/onearg.jl @@ -77,8 +77,9 @@ function compute_ydual_onearg( tx::NTuple, contexts::Vararg{Context,C}, ) where {F,T,C} - (; xdual_tmp) = prep - make_dual!(T, xdual_tmp, x, tx) + # (; xdual_tmp) = prep + # make_dual!(T, xdual_tmp, x, tx) + xdual_tmp = make_dual(T, x, tx) # TODO: discuss reuse of mutable dual array ydual = f(xdual_tmp, map(unwrap, contexts)...) return ydual end diff --git a/DifferentiationInterface/test/Back/ForwardDiff/test.jl b/DifferentiationInterface/test/Back/ForwardDiff/test.jl index 31229c38a..a5db72551 100644 --- a/DifferentiationInterface/test/Back/ForwardDiff/test.jl +++ b/DifferentiationInterface/test/Back/ForwardDiff/test.jl @@ -67,7 +67,7 @@ test_differentiation(AutoForwardDiff(), static_scenarios(); logging=LOGGING) AutoForwardDiff(), filtered_static_scenarios; benchmark=:prepared, - excluded=vcat(SECOND_ORDER, :pullback, :pushforward), # TODO: figure this out + excluded=[:hessian, :pullback], # TODO: figure this out logging=LOGGING, ) @testset "$(row[:scenario])" for row in eachrow(data) From 5391bb45aff2c4fa2499627d132b8a41fe3af041 Mon Sep 17 00:00:00 2001 From: Guillaume Dalle <22795598+gdalle@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:13:42 +0200 Subject: [PATCH 5/5] Simplify static scenarios --- ...erentiationInterfaceTestStaticArraysExt.jl | 29 +------------------ .../src/scenarios/default.jl | 4 +-- 2 files changed, 3 insertions(+), 30 deletions(-) diff --git a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestStaticArraysExt/DifferentiationInterfaceTestStaticArraysExt.jl b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestStaticArraysExt/DifferentiationInterfaceTestStaticArraysExt.jl index 0e7f02d4b..0b8d0d9d2 100644 --- a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestStaticArraysExt/DifferentiationInterfaceTestStaticArraysExt.jl +++ b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestStaticArraysExt/DifferentiationInterfaceTestStaticArraysExt.jl @@ -8,19 +8,10 @@ using SparseArrays: SparseArrays, SparseMatrixCSC, nnz, spdiagm using StaticArrays: MArray, MMatrix, MVector, SArray, SMatrix, SVector mySArray(f::Function) = f -myMArray(f::Function) = f - mySArray(::DIT.NumToArr{A}) where {T,A<:AbstractVector{T}} = DIT.NumToArr(SVector{6,T}) -myMArray(::DIT.NumToArr{A}) where {T,A<:AbstractVector{T}} = DIT.NumToArr(MVector{6,T}) - mySArray(::DIT.NumToArr{A}) where {T,A<:AbstractMatrix{T}} = DIT.NumToArr(SMatrix{2,3,T,6}) -myMArray(::DIT.NumToArr{A}) where {T,A<:AbstractMatrix{T}} = DIT.NumToArr(MMatrix{2,3,T,6}) - mySArray(f::DIT.MultiplyByConstant) = f -myMArray(f::DIT.MultiplyByConstant) = f - mySArray(f::DIT.WritableClosure) = f -myMArray(f::DIT.WritableClosure) = f mySArray(x::Number) = x myMArray(x::Number) = x @@ -36,13 +27,8 @@ function myMArray(x::AbstractMatrix{T}) where {T} end mySArray(x::Tuple) = map(mySArray, x) -myMArray(x::Tuple) = map(myMArray, x) - mySArray(x::DI.Constant) = DI.Constant(mySArray(DI.unwrap(x))) -myMArray(x::DI.Constant) = DI.Constant(myMArray(DI.unwrap(x))) - mySArray(::Nothing) = nothing -myMArray(::Nothing) = nothing function mySArray(scen::Scenario{op,pl_op,pl_fun}) where {op,pl_op,pl_fun} (; f, x, y, tang, contexts, res1, res2) = scen @@ -57,22 +43,9 @@ function mySArray(scen::Scenario{op,pl_op,pl_fun}) where {op,pl_op,pl_fun} ) end -function myMArray(scen::Scenario{op,pl_op,pl_fun}) where {op,pl_op,pl_fun} - (; f, x, y, tang, contexts, res1, res2) = scen - return Scenario{op,pl_op,pl_fun}( - myMArray(f); - x=myMArray(x), - y=pl_fun == :in ? myMArray(y) : myMArray(y), - tang=myMArray(tang), - contexts=myMArray(contexts), - res1=myMArray(res1), - res2=myMArray(res2), - ) -end - function DIT.static_scenarios(args...; kwargs...) scens = DIT.default_scenarios(args...; kwargs...) - return vcat(mySArray.(scens), myMArray.(scens)) + return mySArray.(scens) end end diff --git a/DifferentiationInterfaceTest/src/scenarios/default.jl b/DifferentiationInterfaceTest/src/scenarios/default.jl index 74506155e..1803df72e 100644 --- a/DifferentiationInterfaceTest/src/scenarios/default.jl +++ b/DifferentiationInterfaceTest/src/scenarios/default.jl @@ -71,8 +71,8 @@ end ## Number to array -multiplicator(::Type{A}) where {A<:AbstractVector} = convert(A, float.(1:6)) -multiplicator(::Type{A}) where {A<:AbstractMatrix} = convert(A, reshape(float.(1:6), 2, 3)) +multiplicator(::Type{A}) where {A<:AbstractVector} = convert(A, 1:6) +multiplicator(::Type{A}) where {A<:AbstractMatrix} = convert(A, reshape(1:6, 2, 3)) struct NumToArr{A} end NumToArr(::Type{A}) where {A} = NumToArr{A}()