From f17b7c015218c62458eddc8a57fc16ecbcb375fb Mon Sep 17 00:00:00 2001 From: KristofferC Date: Thu, 15 Aug 2024 09:54:16 +0200 Subject: [PATCH 1/3] Stop precomputing chunk sizes This prevents constant propagation of the length of a static array. Alternative to https://github.com/JuliaDiff/ForwardDiff.jl/pull/707 --- src/prelude.jl | 4 +--- test/GradientTest.jl | 3 +++ test/JacobianTest.jl | 5 ++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/prelude.jl b/src/prelude.jl index 04f62765..7ea098c9 100644 --- a/src/prelude.jl +++ b/src/prelude.jl @@ -7,11 +7,9 @@ const UNARY_PREDICATES = Symbol[:isinf, :isnan, :isfinite, :iseven, :isodd, :isr struct Chunk{N} end -const CHUNKS = [Chunk{i}() for i in 1:DEFAULT_CHUNK_THRESHOLD] - function Chunk(input_length::Integer, threshold::Integer = DEFAULT_CHUNK_THRESHOLD) N = pickchunksize(input_length, threshold) - 0 < N <= DEFAULT_CHUNK_THRESHOLD && return CHUNKS[N] + 0 < N <= DEFAULT_CHUNK_THRESHOLD && return Chunk{N}() return Chunk{N}() end diff --git a/test/GradientTest.jl b/test/GradientTest.jl index a285b51b..5adfc8c7 100644 --- a/test/GradientTest.jl +++ b/test/GradientTest.jl @@ -136,6 +136,9 @@ end @test DiffResults.gradient(sresult1) == DiffResults.gradient(result) @test DiffResults.gradient(sresult2) == DiffResults.gradient(result) @test DiffResults.gradient(sresult3) == DiffResults.gradient(result) + + # make sure this is not a source of type instability + @inferred ForwardDiff.GradientConfig(f, sx) end @testset "exponential function at base zero" begin diff --git a/test/JacobianTest.jl b/test/JacobianTest.jl index 8a767a60..28d6a679 100644 --- a/test/JacobianTest.jl +++ b/test/JacobianTest.jl @@ -222,6 +222,9 @@ for T in (StaticArrays.SArray, StaticArrays.MArray) @test DiffResults.jacobian(sresult1) == DiffResults.jacobian(result) @test DiffResults.jacobian(sresult2) == DiffResults.jacobian(result) @test DiffResults.jacobian(sresult3) == DiffResults.jacobian(result) + + # make sure this is not a source of type instability + @inferred ForwardDiff.JacobianConfig(f, sx) end ######### @@ -237,7 +240,7 @@ end @testset "eigen" begin @test ForwardDiff.jacobian(x -> eigvals(SymTridiagonal(x, x[1:end-1])), [1.,2.]) ≈ [(1 - 3/sqrt(5))/2 (1 - 1/sqrt(5))/2 ; (1 + 3/sqrt(5))/2 (1 + 1/sqrt(5))/2] @test ForwardDiff.jacobian(x -> eigvals(Symmetric(x*x')), [1.,2.]) ≈ [0 0; 2 4] - + x0 = [1.0, 2.0]; ev1(x) = eigen(Symmetric(x*x')).vectors[:,1] @test ForwardDiff.jacobian(ev1, x0) ≈ Calculus.finite_difference_jacobian(ev1, x0) From eb6f1bd61512a7ffdc6a52bd6c72d429cab89344 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Thu, 15 Aug 2024 10:05:09 +0200 Subject: [PATCH 2/3] Update src/prelude.jl Co-authored-by: David Widmann --- src/prelude.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/prelude.jl b/src/prelude.jl index 7ea098c9..9b246e89 100644 --- a/src/prelude.jl +++ b/src/prelude.jl @@ -9,7 +9,6 @@ struct Chunk{N} end function Chunk(input_length::Integer, threshold::Integer = DEFAULT_CHUNK_THRESHOLD) N = pickchunksize(input_length, threshold) - 0 < N <= DEFAULT_CHUNK_THRESHOLD && return Chunk{N}() return Chunk{N}() end From 330440ee919f4c9c80edafdf12b93c29749116f7 Mon Sep 17 00:00:00 2001 From: Kristoffer Date: Thu, 15 Aug 2024 20:11:59 +0200 Subject: [PATCH 3/3] unroll the chunk picking --- src/prelude.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prelude.jl b/src/prelude.jl index 9b246e89..ed4782e9 100644 --- a/src/prelude.jl +++ b/src/prelude.jl @@ -9,7 +9,7 @@ struct Chunk{N} end function Chunk(input_length::Integer, threshold::Integer = DEFAULT_CHUNK_THRESHOLD) N = pickchunksize(input_length, threshold) - return Chunk{N}() + Base.@nif 12 d->(N == d) d->(Chunk{d}()) d->(Chunk{N}()) end function Chunk(x::AbstractArray, threshold::Integer = DEFAULT_CHUNK_THRESHOLD)