From 6deff017965795bd76d899e76a149a5cdd53ce21 Mon Sep 17 00:00:00 2001 From: Michael Abbott Date: Sat, 21 Nov 2020 22:33:35 +0100 Subject: [PATCH 01/22] tie-breaking rules for ==, >, etc. --- src/dual.jl | 44 ++++++++++++++++++++++++++++++++++++++++---- test/runtests.jl | 6 +++--- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/dual.jl b/src/dual.jl index 48e14a7c..c579e285 100644 --- a/src/dual.jl +++ b/src/dual.jl @@ -384,17 +384,53 @@ for pred in UNARY_PREDICATES @eval Base.$(pred)(d::Dual) = $(pred)(value(d)) end -for pred in BINARY_PREDICATES +# BINARY_PREDICATES = Symbol[:isequal, :isless, :<, :>, :(==), :(!=), :(<=), :(>=)] + +for pred in [:isequal, :(==)] + @eval begin + @define_binary_dual_op( + Base.$(pred), + $(pred)(value(x), value(y)) && $(pred)(partials(x), partials(y)), + $(pred)(value(x), y) && $(pred)(partials(x), zero(partials(x))), + $(pred)(x, value(y)) && $(pred)(zero(partials(y)), partials(y)), + ) + end +end + +@define_binary_dual_op( + Base.:(!=), + (!=)(value(x), value(y)) || (!=)(partials(x), partials(y)), + (!=)(value(x), y) || (!=)(partials(x), zero(partials(x))), + (!=)(x, value(y)) || (!=)(zero(partials(y)), partials(y)), +) + +for pred in [:isless, :<, :>, :(<=), :(>=)] @eval begin @define_binary_dual_op( Base.$(pred), - $(pred)(value(x), value(y)), - $(pred)(value(x), y), - $(pred)(x, value(y)) + if value(x) == value(y) # both Dual + $(pred)(partials(x), partials(y)) + else + $(pred)(value(x), value(y)) + end, + if value(x) == y # only x is Dual + $(pred)(partials(x), zero(partials(x))) + else + $(pred)(value(x), value(y)) + end, + if x == value(y) # only y is Dual + $(pred)(zero(partials(y)), partials(y)) + else + $(pred)(value(x), value(y)) + end, ) end end +# @define_binary_dual_op(Base.:(==), false, false, false) +# @define_binary_dual_op(Base.isequal, false, false, false) +# @define_binary_dual_op(Base.:(!=), true, true, true) + ######################## # Promotion/Conversion # ######################## diff --git a/test/runtests.jl b/test/runtests.jl index 0b9b1d8b..1802015a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,9 +4,9 @@ println("Testing Partials...") t = @elapsed include("PartialsTest.jl") println("done (took $t seconds).") -println("Testing Dual...") -t = @elapsed include("DualTest.jl") -println("done (took $t seconds).") +# println("Testing Dual...") +# t = @elapsed include("DualTest.jl") +# println("done (took $t seconds).") println("Testing derivative functionality...") t = @elapsed include("DerivativeTest.jl") From 7db2df206f6ef4ba358901475066dd61206f287f Mon Sep 17 00:00:00 2001 From: Michael Abbott Date: Sun, 22 Nov 2020 18:59:21 +0100 Subject: [PATCH 02/22] simpler rule --- src/dual.jl | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/dual.jl b/src/dual.jl index c579e285..68fed1ba 100644 --- a/src/dual.jl +++ b/src/dual.jl @@ -390,18 +390,18 @@ for pred in [:isequal, :(==)] @eval begin @define_binary_dual_op( Base.$(pred), - $(pred)(value(x), value(y)) && $(pred)(partials(x), partials(y)), - $(pred)(value(x), y) && $(pred)(partials(x), zero(partials(x))), - $(pred)(x, value(y)) && $(pred)(zero(partials(y)), partials(y)), + $(pred)(value(x), value(y)) && $(pred)(partials(x), partials(y)), + $(pred)(value(x), y) && iszero(partials(x)), + $(pred)(x, value(y)) && iszero(partials(y)), ) end end @define_binary_dual_op( Base.:(!=), - (!=)(value(x), value(y)) || (!=)(partials(x), partials(y)), - (!=)(value(x), y) || (!=)(partials(x), zero(partials(x))), - (!=)(x, value(y)) || (!=)(zero(partials(y)), partials(y)), + (!=)(value(x), value(y)) || (!=)(partials(x), partials(y)), + (!=)(value(x), y) || !iszero(partials(x)), + (!=)(x, value(y)) || !iszero(partials(y)), ) for pred in [:isless, :<, :>, :(<=), :(>=)] @@ -413,24 +413,12 @@ for pred in [:isless, :<, :>, :(<=), :(>=)] else $(pred)(value(x), value(y)) end, - if value(x) == y # only x is Dual - $(pred)(partials(x), zero(partials(x))) - else - $(pred)(value(x), value(y)) - end, - if x == value(y) # only y is Dual - $(pred)(zero(partials(y)), partials(y)) - else - $(pred)(value(x), value(y)) - end, + $(pred)(value(x), y), # only x is Dual + $(pred)(x, value(y)), # only y is Dual ) end end -# @define_binary_dual_op(Base.:(==), false, false, false) -# @define_binary_dual_op(Base.isequal, false, false, false) -# @define_binary_dual_op(Base.:(!=), true, true, true) - ######################## # Promotion/Conversion # ######################## From 49c46dec0fb91d23f4a1c50c00b5249ffb911529 Mon Sep 17 00:00:00 2001 From: Michael Abbott Date: Sun, 22 Nov 2020 18:59:53 +0100 Subject: [PATCH 03/22] tests --- test/DualTest.jl | 6 +++--- test/runtests.jl | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/DualTest.jl b/test/DualTest.jl index a01649fe..54437009 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -222,7 +222,7 @@ for N in (0,3), M in (0,4), V in (Int, Float32) # Predicates # #------------# - +#= @test ForwardDiff.isconstant(zero(FDNUM)) @test ForwardDiff.isconstant(one(FDNUM)) @test ForwardDiff.isconstant(FDNUM) == (N == 0) @@ -280,7 +280,7 @@ for N in (0,3), M in (0,4), V in (Int, Float32) @test Dual{TestTag()}(Dual{TestTag()}(2, M_PARTIALS), NESTED_PARTIALS) >= Dual{TestTag()}(Dual{TestTag()}(1, M_PARTIALS2), NESTED_PARTIALS2) @test Dual{TestTag()}(Dual{TestTag()}(1, M_PARTIALS), NESTED_PARTIALS) >= Dual{TestTag()}(Dual{TestTag()}(1, M_PARTIALS2), NESTED_PARTIALS2) @test !(Dual{TestTag()}(Dual{TestTag()}(1, M_PARTIALS), NESTED_PARTIALS) >= Dual{TestTag()}(Dual{TestTag()}(2, M_PARTIALS2), NESTED_PARTIALS2)) - +=# @test isnan(Dual{TestTag()}(NaN, PARTIALS)) @test !(isnan(FDNUM)) @@ -344,7 +344,7 @@ for N in (0,3), M in (0,4), V in (Int, Float32) @test typeof(WIDE_NESTED_FDNUM) === Dual{TestTag(),Dual{TestTag(),WIDE_T,M},N} @test value(WIDE_FDNUM) == PRIMAL - @test value(WIDE_NESTED_FDNUM) == PRIMAL + # @test !(value(WIDE_NESTED_FDNUM) == PRIMAL) @test convert(Dual, FDNUM) === FDNUM @test convert(Dual, NESTED_FDNUM) === NESTED_FDNUM diff --git a/test/runtests.jl b/test/runtests.jl index 1802015a..0b9b1d8b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,9 +4,9 @@ println("Testing Partials...") t = @elapsed include("PartialsTest.jl") println("done (took $t seconds).") -# println("Testing Dual...") -# t = @elapsed include("DualTest.jl") -# println("done (took $t seconds).") +println("Testing Dual...") +t = @elapsed include("DualTest.jl") +println("done (took $t seconds).") println("Testing derivative functionality...") t = @elapsed include("DerivativeTest.jl") From 827ac198d9f3ff156761de7357e8d3c741f1ee51 Mon Sep 17 00:00:00 2001 From: Michael Abbott Date: Thu, 26 Nov 2020 16:03:42 +0100 Subject: [PATCH 04/22] only alter equality, not ordering --- src/dual.jl | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/dual.jl b/src/dual.jl index 68fed1ba..a8778538 100644 --- a/src/dual.jl +++ b/src/dual.jl @@ -384,7 +384,9 @@ for pred in UNARY_PREDICATES @eval Base.$(pred)(d::Dual) = $(pred)(value(d)) end -# BINARY_PREDICATES = Symbol[:isequal, :isless, :<, :>, :(==), :(!=), :(<=), :(>=)] +# BINARY_PREDICATES = Symbol[:isequal, :isless, :<, :>, :(==), :(!=), :(<=), :(>=)] # prelude.jl + +Base.iszero(x::Dual) = iszero(value(x)) && iszero(partials(x)) for pred in [:isequal, :(==)] @eval begin @@ -408,13 +410,9 @@ for pred in [:isless, :<, :>, :(<=), :(>=)] @eval begin @define_binary_dual_op( Base.$(pred), - if value(x) == value(y) # both Dual - $(pred)(partials(x), partials(y)) - else - $(pred)(value(x), value(y)) - end, - $(pred)(value(x), y), # only x is Dual - $(pred)(x, value(y)), # only y is Dual + $(pred)(value(x), value(y)), + $(pred)(value(x), y), + $(pred)(x, value(y)), ) end end From 5c8d9975273314322b66d140dba14573cfd1e444 Mon Sep 17 00:00:00 2001 From: Michael Abbott Date: Thu, 26 Nov 2020 16:07:28 +0100 Subject: [PATCH 05/22] fix tests --- test/DualTest.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/DualTest.jl b/test/DualTest.jl index 54437009..ff29109e 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -222,7 +222,7 @@ for N in (0,3), M in (0,4), V in (Int, Float32) # Predicates # #------------# -#= + @test ForwardDiff.isconstant(zero(FDNUM)) @test ForwardDiff.isconstant(one(FDNUM)) @test ForwardDiff.isconstant(FDNUM) == (N == 0) @@ -231,13 +231,13 @@ for N in (0,3), M in (0,4), V in (Int, Float32) @test ForwardDiff.isconstant(one(NESTED_FDNUM)) @test ForwardDiff.isconstant(NESTED_FDNUM) == (N == 0) - @test isequal(FDNUM, Dual{TestTag()}(PRIMAL, PARTIALS2)) + @test isequal(FDNUM, Dual{TestTag()}(PRIMAL, PARTIALS2)) == (N == 0) @test isequal(PRIMAL, PRIMAL2) == isequal(FDNUM, FDNUM2) - @test isequal(NESTED_FDNUM, Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS2), NESTED_PARTIALS2)) + @test isequal(NESTED_FDNUM, Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS2), NESTED_PARTIALS2)) == (N == M == 0) @test isequal(PRIMAL, PRIMAL2) == isequal(NESTED_FDNUM, NESTED_FDNUM2) - @test FDNUM == Dual{TestTag()}(PRIMAL, PARTIALS2) + @test (FDNUM == Dual{TestTag()}(PRIMAL, PARTIALS2)) == (N == 0) @test (PRIMAL == PRIMAL2) == (FDNUM == FDNUM2) @test (PRIMAL == PRIMAL2) == (NESTED_FDNUM == NESTED_FDNUM2) @@ -280,7 +280,7 @@ for N in (0,3), M in (0,4), V in (Int, Float32) @test Dual{TestTag()}(Dual{TestTag()}(2, M_PARTIALS), NESTED_PARTIALS) >= Dual{TestTag()}(Dual{TestTag()}(1, M_PARTIALS2), NESTED_PARTIALS2) @test Dual{TestTag()}(Dual{TestTag()}(1, M_PARTIALS), NESTED_PARTIALS) >= Dual{TestTag()}(Dual{TestTag()}(1, M_PARTIALS2), NESTED_PARTIALS2) @test !(Dual{TestTag()}(Dual{TestTag()}(1, M_PARTIALS), NESTED_PARTIALS) >= Dual{TestTag()}(Dual{TestTag()}(2, M_PARTIALS2), NESTED_PARTIALS2)) -=# + @test isnan(Dual{TestTag()}(NaN, PARTIALS)) @test !(isnan(FDNUM)) @@ -344,7 +344,7 @@ for N in (0,3), M in (0,4), V in (Int, Float32) @test typeof(WIDE_NESTED_FDNUM) === Dual{TestTag(),Dual{TestTag(),WIDE_T,M},N} @test value(WIDE_FDNUM) == PRIMAL - # @test !(value(WIDE_NESTED_FDNUM) == PRIMAL) + @test (value(WIDE_NESTED_FDNUM) == PRIMAL) == (M == 0) @test convert(Dual, FDNUM) === FDNUM @test convert(Dual, NESTED_FDNUM) === NESTED_FDNUM From b38a284d562d73d5820f892044258106c57a9e53 Mon Sep 17 00:00:00 2001 From: Michael Abbott Date: Fri, 27 Nov 2020 10:10:14 +0100 Subject: [PATCH 06/22] add a test of issue 197 --- test/GradientTest.jl | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/GradientTest.jl b/test/GradientTest.jl index 707fcd68..e7b96c71 100644 --- a/test/GradientTest.jl +++ b/test/GradientTest.jl @@ -3,6 +3,7 @@ module GradientTest import Calculus using Test +using LinearAlgebra using ForwardDiff using ForwardDiff: Dual, Tag using StaticArrays @@ -148,6 +149,10 @@ end @test isequal(ForwardDiff.gradient(t -> t[1]^t[2], [0.0, 1.5]), [0.0, 0.0]) end +############# +# bug fixes # +############# + # Issue 399 @testset "chunk size zero" begin f_const(x) = 1.0 @@ -162,6 +167,7 @@ end @test_throws DimensionMismatch ForwardDiff.gradient(identity, fill(2pi, 10^6)) # chunk_mode_gradient end +# Issue 548 @testset "ArithmeticStyle" begin function f(p) sum(collect(0.0:p[1]:p[2])) @@ -169,4 +175,21 @@ end @test ForwardDiff.gradient(f, [0.2,25.0]) == [7875.0, 0.0] end +# Issue 197 +@testset "det with branches" begin + det2(A) = return ( + A[1,1]*(A[2,2]*A[3,3]-A[2,3]*A[3,2]) - + A[1,2]*(A[2,1]*A[3,3]-A[2,3]*A[3,1]) + + A[1,3]*(A[2,1]*A[3,2]-A[2,2]*A[3,1]) + ) + + A = [1 0 0; 0 2 0; 0 pi 3] + @test det2(A) == det(A) == 6 + @test istril(A) + + ∇A = [6 0 0; 0 3 -pi; 0 0 2] + @test ForwardDiff.gradient(det2, A) ≈ ∇A + @test ForwardDiff.gradient(det, A) ≈ ∇A +end + end # module From f65b1fc9bbcb33f8c77a7470e0070dff1411264f Mon Sep 17 00:00:00 2001 From: Michael Abbott Date: Fri, 27 Nov 2020 10:14:10 +0100 Subject: [PATCH 07/22] add test for issue 407 --- test/GradientTest.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/GradientTest.jl b/test/GradientTest.jl index e7b96c71..73fdddce 100644 --- a/test/GradientTest.jl +++ b/test/GradientTest.jl @@ -190,6 +190,10 @@ end ∇A = [6 0 0; 0 3 -pi; 0 0 2] @test ForwardDiff.gradient(det2, A) ≈ ∇A @test ForwardDiff.gradient(det, A) ≈ ∇A + + # And issue 407 + @test ForwardDiff.hessian(det, A) ≈ ForwardDiff.hessian(det2, A) + end end # module From 0ed7fc63d78576a5a52c41ccf60bb50ee0d8dfa3 Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Wed, 28 Jul 2021 09:06:05 -0400 Subject: [PATCH 08/22] add test from 536 --- test/GradientTest.jl | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/GradientTest.jl b/test/GradientTest.jl index 73fdddce..0ee1e502 100644 --- a/test/GradientTest.jl +++ b/test/GradientTest.jl @@ -193,7 +193,21 @@ end # And issue 407 @test ForwardDiff.hessian(det, A) ≈ ForwardDiff.hessian(det2, A) +end + +@testset "branches in mul!" begin + a, b = rand(3,3), rand(3,3) + # Issue 536, version with 3-arg *, Julia 1.7: + @test ForwardDiff.derivative(x -> sum(x*a*b), 0.0) ≈ sum(a * b) + + # version with just mul! + dx = ForwardDiff.derivative(0.0) do x + c = similar(a, typeof(x)) + mul!(c, a, b, x, false) + sum(c) + end + @test dx ≈ sum(a * b) end end # module From 81c73bd7ff0a09534b103af5bc849e42e266e849 Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Thu, 12 Aug 2021 22:32:51 -0400 Subject: [PATCH 09/22] v0.11 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index a98f72a2..933ddb52 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ForwardDiff" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.32" +version = "0.11.0" [deps] CommonSubexpressions = "bbf7d656-a473-5ed7-a52c-81e309532950" From c9a4acb7a96502c84b401f6ef4f7aaaaf61f76d3 Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Thu, 12 Aug 2021 23:17:15 -0400 Subject: [PATCH 10/22] tests --- test/DualTest.jl | 4 +++- test/GradientTest.jl | 14 ++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/test/DualTest.jl b/test/DualTest.jl index ff29109e..103dd870 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -235,7 +235,9 @@ for N in (0,3), M in (0,4), V in (Int, Float32) @test isequal(PRIMAL, PRIMAL2) == isequal(FDNUM, FDNUM2) @test isequal(NESTED_FDNUM, Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS2), NESTED_PARTIALS2)) == (N == M == 0) - @test isequal(PRIMAL, PRIMAL2) == isequal(NESTED_FDNUM, NESTED_FDNUM2) + # @test isequal(PRIMAL, PRIMAL2) == isequal(NESTED_FDNUM, NESTED_FDNUM2) + + @info "weird test?" N M V PRIMAL PRIMAL2 NESTED_FDNUM NESTED_FDNUM2 @test (FDNUM == Dual{TestTag()}(PRIMAL, PARTIALS2)) == (N == 0) @test (PRIMAL == PRIMAL2) == (FDNUM == FDNUM2) diff --git a/test/GradientTest.jl b/test/GradientTest.jl index 0ee1e502..8ec0d5d3 100644 --- a/test/GradientTest.jl +++ b/test/GradientTest.jl @@ -201,13 +201,15 @@ end # Issue 536, version with 3-arg *, Julia 1.7: @test ForwardDiff.derivative(x -> sum(x*a*b), 0.0) ≈ sum(a * b) - # version with just mul! - dx = ForwardDiff.derivative(0.0) do x - c = similar(a, typeof(x)) - mul!(c, a, b, x, false) - sum(c) + if VERSION >= v"1.3" + # version with just mul! + dx = ForwardDiff.derivative(0.0) do x + c = similar(a, typeof(x)) + mul!(c, a, b, x, false) + sum(c) + end + @test dx ≈ sum(a * b) end - @test dx ≈ sum(a * b) end end # module From 0f5a9b797434c91f5b2c50f46f8f3d38edbcaa5d Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Fri, 13 Aug 2021 10:13:25 -0400 Subject: [PATCH 11/22] let's add testsets --- test/DualTest.jl | 4 +- test/GradientTest.jl | 4 +- test/PartialsTest.jl | 2 +- test/runtests.jl | 90 +++++++++++++++++++++++++------------------- 4 files changed, 56 insertions(+), 44 deletions(-) diff --git a/test/DualTest.jl b/test/DualTest.jl index 103dd870..ec098cac 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -30,7 +30,7 @@ ForwardDiff.:≺(::Int, ::Type{TestTag()}) = false ForwardDiff.:≺(::Type{TestTag}, ::Type{OuterTestTag}) = true ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false -for N in (0,3), M in (0,4), V in (Int, Float32) +@testset "Dual{TestTag(),$V,$N} and Dual{TestTag(),Dual{TestTag(),$V,$M},$N}" for N in (0,3), M in (0,4), V in (Int, Float32) println(" ...testing Dual{TestTag(),$V,$N} and Dual{TestTag(),Dual{TestTag(),$V,$M},$N}") PARTIALS = Partials{N,V}(ntuple(n -> intrand(V), N)) @@ -237,7 +237,7 @@ for N in (0,3), M in (0,4), V in (Int, Float32) @test isequal(NESTED_FDNUM, Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS2), NESTED_PARTIALS2)) == (N == M == 0) # @test isequal(PRIMAL, PRIMAL2) == isequal(NESTED_FDNUM, NESTED_FDNUM2) - @info "weird test?" N M V PRIMAL PRIMAL2 NESTED_FDNUM NESTED_FDNUM2 + @info "Predicates" N M V PRIMAL PRIMAL2 NESTED_FDNUM NESTED_FDNUM2 @test (FDNUM == Dual{TestTag()}(PRIMAL, PARTIALS2)) == (N == 0) @test (PRIMAL == PRIMAL2) == (FDNUM == FDNUM2) diff --git a/test/GradientTest.jl b/test/GradientTest.jl index 8ec0d5d3..5478088d 100644 --- a/test/GradientTest.jl +++ b/test/GradientTest.jl @@ -84,9 +84,9 @@ end println(" ...testing specialized StaticArray codepaths") -x = rand(3, 3) +@testset "$T" for T in (StaticArrays.SArray, StaticArrays.MArray) + x = rand(3, 3) -for T in (StaticArrays.SArray, StaticArrays.MArray) sx = T{Tuple{3,3}}(x) cfg = ForwardDiff.GradientConfig(nothing, x) diff --git a/test/PartialsTest.jl b/test/PartialsTest.jl index 39fb05d7..c9631c72 100644 --- a/test/PartialsTest.jl +++ b/test/PartialsTest.jl @@ -7,7 +7,7 @@ using ForwardDiff: Partials samerng() = MersenneTwister(1) -for N in (0, 3), T in (Int, Float32, Float64) +@testset "Partials{$N,$T}" for N in (0, 3), T in (Int, Float32, Float64) println(" ...testing Partials{$N,$T}") VALUES = (rand(T,N)...,) diff --git a/test/runtests.jl b/test/runtests.jl index 0b9b1d8b..f8845271 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,39 +1,51 @@ -using ForwardDiff - -println("Testing Partials...") -t = @elapsed include("PartialsTest.jl") -println("done (took $t seconds).") - -println("Testing Dual...") -t = @elapsed include("DualTest.jl") -println("done (took $t seconds).") - -println("Testing derivative functionality...") -t = @elapsed include("DerivativeTest.jl") -println("done (took $t seconds).") - -println("Testing gradient functionality...") -t = @elapsed include("GradientTest.jl") -println("done (took $t seconds).") - -println("Testing jacobian functionality...") -t = @elapsed include("JacobianTest.jl") -println("done (took $t seconds).") - -println("Testing hessian functionality...") -t = @elapsed include("HessianTest.jl") -println("done (took $t seconds).") - -println("Testing perturbation confusion functionality...") -t = @elapsed include("ConfusionTest.jl") -println("done (took $t seconds).") - -println("Testing miscellaneous functionality...") -t = @elapsed include("MiscTest.jl") -println("done (took $t seconds).") - -if VERSION >= v"1.5-" - println("Testing allocations...") - t = @elapsed include("AllocationsTest.jl") - println("done (took $t seconds).") -end +using ForwardDiff, Test + +@testset "ForwardDiff" begin + @testset "Partials" begin + println("Testing Partials...") + t = @elapsed include("PartialsTest.jl") + println("done (took $t seconds).") + end + @testset "Dual" begin + println("Testing Dual...") + t = @elapsed include("DualTest.jl") + println("done (took $t seconds).") + end + @testset "Derivative" begin + println("Testing derivative functionality...") + t = @elapsed include("DerivativeTest.jl") + println("done (took $t seconds).") + end + @testset "Gradient" begin + println("Testing gradient functionality...") + t = @elapsed include("GradientTest.jl") + println("done (took $t seconds).") + end + @testset "Jacobian" begin + println("Testing jacobian functionality...") + t = @elapsed include("JacobianTest.jl") + println("done (took $t seconds).") + end + @testset "Hessian" begin + println("Testing hessian functionality...") + t = @elapsed include("HessianTest.jl") + println("done (took $t seconds).") + end + @testset "Perturbation confusion" begin + println("Testing perturbation confusion functionality...") + t = @elapsed include("ConfusionTest.jl") + println("done (took $t seconds).") + end + @testset "Miscellaneous" begin + println("Testing miscellaneous functionality...") + t = @elapsed include("MiscTest.jl") + println("done (took $t seconds).") + end + if VERSION >= v"1.5-" + @testset "Allocations" begin + println("Testing allocations...") + t = @elapsed include("AllocationsTest.jl") + println("done (took $t seconds).") + end + end +end \ No newline at end of file From c7f1a1019c78b365c17c0bef2bfd3ddabd67190c Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Fri, 13 Aug 2021 11:45:11 -0400 Subject: [PATCH 12/22] tests --- test/DualTest.jl | 24 +++++++++++++++++++--- test/GradientTest.jl | 4 ++-- test/runtests.jl | 48 +++++++++++++++++++++++--------------------- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/test/DualTest.jl b/test/DualTest.jl index ec098cac..10f7e33b 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -222,6 +222,7 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false # Predicates # #------------# + @testset "Predicates" begin @test ForwardDiff.isconstant(zero(FDNUM)) @test ForwardDiff.isconstant(one(FDNUM)) @@ -234,10 +235,13 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false @test isequal(FDNUM, Dual{TestTag()}(PRIMAL, PARTIALS2)) == (N == 0) @test isequal(PRIMAL, PRIMAL2) == isequal(FDNUM, FDNUM2) - @test isequal(NESTED_FDNUM, Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS2), NESTED_PARTIALS2)) == (N == M == 0) - # @test isequal(PRIMAL, PRIMAL2) == isequal(NESTED_FDNUM, NESTED_FDNUM2) + # Recall that FDNUM = Dual{TestTag()}(PRIMAL, PARTIALS) has N partials, + # and FDNUM2 has everything with a 2, and all random numbers nonzero. + # M is the length of M_PARTIALS, which affects: + # NESTED_FDNUM = Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS), NESTED_PARTIALS) - @info "Predicates" N M V PRIMAL PRIMAL2 NESTED_FDNUM NESTED_FDNUM2 + @test isequal(NESTED_FDNUM, Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS2), NESTED_PARTIALS2)) == (N == M == 0) + @test isequal(NESTED_FDNUM, NESTED_FDNUM2) == isequal(PRIMAL, PRIMAL2) && (N == M == 0) @test (FDNUM == Dual{TestTag()}(PRIMAL, PARTIALS2)) == (N == 0) @test (PRIMAL == PRIMAL2) == (FDNUM == FDNUM2) @@ -322,6 +326,7 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false @test isodd(Dual{TestTag()}(Dual{TestTag()}(1))) @test !(isodd(Dual{TestTag()}(Dual{TestTag()}(2)))) + end ######################## # Promotion/Conversion # ######################## @@ -395,8 +400,11 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false # Division # #----------# + @testset "Division" begin if M > 0 && N > 0 + # Recall that FDNUM = Dual{TestTag()}(PRIMAL, PARTIALS) has N partials, + # all random numbers nonzero, and FDNUM2 another draw. M only affects NESTED_FDNUM. @test Dual{1}(FDNUM) / Dual{1}(PRIMAL) === Dual{1}(FDNUM / PRIMAL) @test Dual{1}(PRIMAL) / Dual{1}(FDNUM) === Dual{1}(PRIMAL / FDNUM) @test_broken Dual{1}(FDNUM) / FDNUM2 === Dual{1}(FDNUM / FDNUM2) @@ -413,8 +421,12 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false @test dual_isapprox(NESTED_FDNUM / PRIMAL, Dual{TestTag()}(value(NESTED_FDNUM) / PRIMAL, partials(NESTED_FDNUM) / PRIMAL)) @test dual_isapprox(PRIMAL / NESTED_FDNUM, Dual{TestTag()}(PRIMAL / value(NESTED_FDNUM), (-(PRIMAL) / value(NESTED_FDNUM)^2) * partials(NESTED_FDNUM))) + end + # Exponentiation # #----------------# + @testset "Exponentiation" begin + # If V == Int, the LHS terms are Int's. Large inputs cause integer overflow # within the generic fallback of `isapprox`, resulting in a DomainError. # Promote to Float64 to avoid issues. @@ -428,6 +440,7 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false @test partials(NaNMath.pow(Dual{TestTag()}(-2.0, 1.0), Dual{TestTag()}(2.0, 0.0)), 1) == -4.0 + end ################################### # General Mathematical Operations # ################################### @@ -520,6 +533,7 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false # Special Cases # #---------------# + @testset "Special Cases" begin @test_broken dual_isapprox(hypot(FDNUM, FDNUM2, FDNUM), sqrt(2*(FDNUM^2) + FDNUM2^2)) @test_broken dual_isapprox(hypot(FDNUM, FDNUM2, FDNUM3), sqrt(FDNUM^2 + FDNUM2^2 + FDNUM3^2)) @@ -570,6 +584,10 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false end end +############# +# bug fixes # +############# + @testset "Exponentiation of zero" begin x0 = 0.0 x1 = Dual{:t1}(x0, 1.0) diff --git a/test/GradientTest.jl b/test/GradientTest.jl index 5478088d..f5d9db82 100644 --- a/test/GradientTest.jl +++ b/test/GradientTest.jl @@ -20,7 +20,7 @@ x = [0.1, 0.2, 0.3] v = f(x) g = [-9.4, 15.6, 52.0] -for c in (1, 2, 3), tag in (nothing, Tag(f, eltype(x))) +@testset "Rosenbrock, chunk size = $c and tag = $(repr(tag))" for c in (1, 2, 3), tag in (nothing, Tag(f, eltype(x))) println(" ...running hardcoded test with chunk size = $c and tag = $(repr(tag))") cfg = ForwardDiff.GradientConfig(f, x, ForwardDiff.Chunk{c}(), tag) @@ -56,7 +56,7 @@ cfgx = ForwardDiff.GradientConfig(sin, x) # test vs. Calculus.jl # ######################## -for f in DiffTests.VECTOR_TO_NUMBER_FUNCS +@testset "$f" for f in DiffTests.VECTOR_TO_NUMBER_FUNCS v = f(X) g = ForwardDiff.gradient(f, X) @test isapprox(g, Calculus.gradient(f, X), atol=FINITEDIFF_ERROR) diff --git a/test/runtests.jl b/test/runtests.jl index f8845271..38ef3d4c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,51 +1,53 @@ using ForwardDiff, Test @testset "ForwardDiff" begin + t0 = time() @testset "Partials" begin - println("Testing Partials...") + println("##### Testing Partials...") t = @elapsed include("PartialsTest.jl") - println("done (took $t seconds).") + println("##### done (took $t seconds).") end @testset "Dual" begin - println("Testing Dual...") + println("##### Testing Dual...") t = @elapsed include("DualTest.jl") - println("done (took $t seconds).") + println("##### done (took $t seconds).") end - @testset "Derivative" begin - println("Testing derivative functionality...") + @testset "Derivatives" begin + println("##### Testing derivative functionality...") t = @elapsed include("DerivativeTest.jl") - println("done (took $t seconds).") + println("##### done (took $t seconds).") end - @testset "Gradient" begin - println("Testing gradient functionality...") + @testset "Gradients" begin + println("##### Testing gradient functionality...") t = @elapsed include("GradientTest.jl") - println("done (took $t seconds).") + println("##### done (took $t seconds).") end - @testset "Jacobian" begin - println("Testing jacobian functionality...") + @testset "Jacobians" begin + println("##### Testing jacobian functionality...") t = @elapsed include("JacobianTest.jl") - println("done (took $t seconds).") + println("##### done (took $t seconds).") end - @testset "Hessian" begin - println("Testing hessian functionality...") + @testset "Hessians" begin + println("##### Testing hessian functionality...") t = @elapsed include("HessianTest.jl") - println("done (took $t seconds).") + println("##### done (took $t seconds).") end - @testset "Perturbation confusion" begin - println("Testing perturbation confusion functionality...") + @testset "Perturbation Confusion" begin + println("##### Testing perturbation confusion functionality...") t = @elapsed include("ConfusionTest.jl") - println("done (took $t seconds).") + println("##### done (took $t seconds).") end @testset "Miscellaneous" begin - println("Testing miscellaneous functionality...") + println("##### Testing miscellaneous functionality...") t = @elapsed include("MiscTest.jl") - println("done (took $t seconds).") + println("##### done (took $t seconds).") end if VERSION >= v"1.5-" @testset "Allocations" begin - println("Testing allocations...") + println("##### Testing allocations...") t = @elapsed include("AllocationsTest.jl") - println("done (took $t seconds).") + println("##### done (took $t seconds).") end end + println("##### Running all ForwardDiff tests took $(t0 - time()) seconds.") end \ No newline at end of file From fb37753d211e2a55b74b0d6df1658a4fa615a1ad Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Mon, 1 Nov 2021 20:21:29 -0400 Subject: [PATCH 13/22] add test for https://github.com/JuliaDiff/ForwardDiff.jl/issues/551 --- test/HessianTest.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/HessianTest.jl b/test/HessianTest.jl index 1df4232b..00026854 100644 --- a/test/HessianTest.jl +++ b/test/HessianTest.jl @@ -157,4 +157,11 @@ for T in (StaticArrays.SArray, StaticArrays.MArray) @test DiffResults.hessian(sresult3) == DiffResults.hessian(result) end +@testset "branches in dot" begin + # https://github.com/JuliaDiff/ForwardDiff.jl/issues/551 + H = [1 2 3; 4 5 6; 7 8 9]; + @test ForwardDiff.hessian(x->dot(x,H,x), fill(0.00001, 3)) ≈ [2 6 10; 6 10 14; 10 14 18] + @test ForwardDiff.hessian(x->dot(x,H,x), zeros(3)) ≈ [2 6 10; 6 10 14; 10 14 18] +end + end # module From d5fd6ae11bd0527e72abcd3facc435373000672b Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Tue, 9 Nov 2021 16:51:17 -0500 Subject: [PATCH 14/22] dot, show --- test/DualTest.jl | 1 + test/HessianTest.jl | 1 + 2 files changed, 2 insertions(+) diff --git a/test/DualTest.jl b/test/DualTest.jl index 10f7e33b..d2214942 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -240,6 +240,7 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false # M is the length of M_PARTIALS, which affects: # NESTED_FDNUM = Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS), NESTED_PARTIALS) +@show N M @test isequal(NESTED_FDNUM, Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS2), NESTED_PARTIALS2)) == (N == M == 0) @test isequal(NESTED_FDNUM, NESTED_FDNUM2) == isequal(PRIMAL, PRIMAL2) && (N == M == 0) diff --git a/test/HessianTest.jl b/test/HessianTest.jl index 00026854..3f8b08cb 100644 --- a/test/HessianTest.jl +++ b/test/HessianTest.jl @@ -3,6 +3,7 @@ module HessianTest import Calculus using Test +using LinearAlgebra using ForwardDiff using ForwardDiff: Dual, Tag using StaticArrays From 9b27df7433df90d8d2db16b9c5be42b948e040f3 Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Sat, 19 Mar 2022 18:34:59 -0500 Subject: [PATCH 15/22] tests --- test/DualTest.jl | 7 ++++--- test/runtests.jl | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/test/DualTest.jl b/test/DualTest.jl index d2214942..bcf6e094 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -30,7 +30,7 @@ ForwardDiff.:≺(::Int, ::Type{TestTag()}) = false ForwardDiff.:≺(::Type{TestTag}, ::Type{OuterTestTag}) = true ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false -@testset "Dual{TestTag(),$V,$N} and Dual{TestTag(),Dual{TestTag(),$V,$M},$N}" for N in (0,3), M in (0,4), V in (Int, Float32) +@testset "Dual{Z,$V,$N} and Dual{Z,Dual{Z,$V,$M},$N}" for N in (0,3), M in (0,4), V in (Int, Float32) println(" ...testing Dual{TestTag(),$V,$N} and Dual{TestTag(),Dual{TestTag(),$V,$M},$N}") PARTIALS = Partials{N,V}(ntuple(n -> intrand(V), N)) @@ -240,9 +240,10 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false # M is the length of M_PARTIALS, which affects: # NESTED_FDNUM = Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS), NESTED_PARTIALS) -@show N M + @show N M NESTED_FDNUM PRIMAL M_PARTIALS2 NESTED_PARTIALS2 @test isequal(NESTED_FDNUM, Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS2), NESTED_PARTIALS2)) == (N == M == 0) - @test isequal(NESTED_FDNUM, NESTED_FDNUM2) == isequal(PRIMAL, PRIMAL2) && (N == M == 0) + @show N M NESTED_FDNUM NESTED_FDNUM2 PRIMAL PRIMAL2 + @test isequal(NESTED_FDNUM, NESTED_FDNUM2) == isequal(PRIMAL, PRIMAL2) @test (FDNUM == Dual{TestTag()}(PRIMAL, PARTIALS2)) == (N == 0) @test (PRIMAL == PRIMAL2) == (FDNUM == FDNUM2) diff --git a/test/runtests.jl b/test/runtests.jl index 38ef3d4c..d00acfb2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,6 @@ using ForwardDiff, Test -@testset "ForwardDiff" begin +@testset "ForwardDiff.jl" begin t0 = time() @testset "Partials" begin println("##### Testing Partials...") From 37aedec667c65620bd661c930b4fb7080efe887d Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Sat, 23 Apr 2022 19:44:41 -0400 Subject: [PATCH 16/22] test from discourse, random seed --- test/GradientTest.jl | 8 +++++++- test/JacobianTest.jl | 4 ++++ test/runtests.jl | 6 +++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/test/GradientTest.jl b/test/GradientTest.jl index f5d9db82..13a7a354 100644 --- a/test/GradientTest.jl +++ b/test/GradientTest.jl @@ -175,8 +175,8 @@ end @test ForwardDiff.gradient(f, [0.2,25.0]) == [7875.0, 0.0] end -# Issue 197 @testset "det with branches" begin + # Issue 197 det2(A) = return ( A[1,1]*(A[2,2]*A[3,3]-A[2,3]*A[3,2]) - A[1,2]*(A[2,1]*A[3,3]-A[2,3]*A[3,1]) + @@ -193,6 +193,12 @@ end # And issue 407 @test ForwardDiff.hessian(det, A) ≈ ForwardDiff.hessian(det2, A) + + # https://discourse.julialang.org/t/forwarddiff-and-zygote-return-wrong-jacobian-for-log-det-l/77961 + S = [1.0 0.8; 0.8 1.0] + L = cholesky(S).L + @test ForwardDiff.gradient(L -> log(det(L)), Matrix(L)) ≈ [1.0 -1.3333333333333337; 0.0 1.666666666666667] + @test ForwardDiff.gradient(L -> logdet(L), Matrix(L)) ≈ [1.0 -1.3333333333333337; 0.0 1.666666666666667] end @testset "branches in mul!" begin diff --git a/test/JacobianTest.jl b/test/JacobianTest.jl index 69f9409c..5f926bc7 100644 --- a/test/JacobianTest.jl +++ b/test/JacobianTest.jl @@ -226,6 +226,10 @@ for T in (StaticArrays.SArray, StaticArrays.MArray) @test DiffResults.jacobian(sresult3) == DiffResults.jacobian(result) end +######### +# misc. # +######### + @testset "dimension errors for jacobian" begin @test_throws DimensionMismatch ForwardDiff.jacobian(identity, 2pi) # input @test_throws DimensionMismatch ForwardDiff.jacobian(sum, fill(2pi, 2)) # vector_mode_jacobian diff --git a/test/runtests.jl b/test/runtests.jl index d00acfb2..e97b40ee 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,4 +1,8 @@ -using ForwardDiff, Test +using ForwardDiff, Test, Random + +SEED = trunc(Int, time()) +println("Testing with Random.seed!($SEED)") +Random.seed!(SEED) @testset "ForwardDiff.jl" begin t0 = time() From 4805ed38bde270a13e94278daba8a0bbc1063c62 Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Sat, 23 Apr 2022 20:31:46 -0400 Subject: [PATCH 17/22] fixup --- test/DualTest.jl | 34 +++++++++++++++++++++++----------- test/runtests.jl | 4 ++-- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/test/DualTest.jl b/test/DualTest.jl index bcf6e094..455aef2c 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -44,6 +44,13 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false PARTIALS3 = Partials{N,V}(ntuple(n -> intrand(V), N)) PRIMAL3 = intrand(V) FDNUM3 = Dual{TestTag()}(PRIMAL3, PARTIALS3) + + if !allunique([PRIMAL, PRIMAL2, PRIMAL3]) + @info "testing with non-unique primals" PRIMAL PRIMAL2 PRIMAL3 + end + if N > 0 && !allunique([PARTIALS, PARTIALS2, PARTIALS3]) + @info "testing with non-unique partials" PARTIALS PARTIALS2 PARTIALS3 + end M_PARTIALS = Partials{M,V}(ntuple(m -> intrand(V), M)) NESTED_PARTIALS = convert(Partials{N,Dual{TestTag(),V,M}}, PARTIALS) @@ -232,22 +239,27 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false @test ForwardDiff.isconstant(one(NESTED_FDNUM)) @test ForwardDiff.isconstant(NESTED_FDNUM) == (N == 0) - @test isequal(FDNUM, Dual{TestTag()}(PRIMAL, PARTIALS2)) == (N == 0) - @test isequal(PRIMAL, PRIMAL2) == isequal(FDNUM, FDNUM2) - # Recall that FDNUM = Dual{TestTag()}(PRIMAL, PARTIALS) has N partials, # and FDNUM2 has everything with a 2, and all random numbers nonzero. # M is the length of M_PARTIALS, which affects: # NESTED_FDNUM = Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS), NESTED_PARTIALS) - @show N M NESTED_FDNUM PRIMAL M_PARTIALS2 NESTED_PARTIALS2 - @test isequal(NESTED_FDNUM, Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS2), NESTED_PARTIALS2)) == (N == M == 0) - @show N M NESTED_FDNUM NESTED_FDNUM2 PRIMAL PRIMAL2 - @test isequal(NESTED_FDNUM, NESTED_FDNUM2) == isequal(PRIMAL, PRIMAL2) - - @test (FDNUM == Dual{TestTag()}(PRIMAL, PARTIALS2)) == (N == 0) - @test (PRIMAL == PRIMAL2) == (FDNUM == FDNUM2) - @test (PRIMAL == PRIMAL2) == (NESTED_FDNUM == NESTED_FDNUM2) + @test (FDNUM == Dual{TestTag()}(PRIMAL, PARTIALS2)) == (PARTIALS == PARTIALS2) + @test isequal(FDNUM, Dual{TestTag()}(PRIMAL, PARTIALS2)) == (PARTIALS == PARTIALS2) + @test isequal(NESTED_FDNUM, Dual{TestTag()}(Dual{TestTag()}(PRIMAL, M_PARTIALS2), NESTED_PARTIALS2)) == ((M_PARTIALS == M_PARTIALS2) && (NESTED_PARTIALS == NESTED_PARTIALS2)) + + if PRIMAL == PRIMAL2 + @test isequal(FDNUM, Dual{TestTag()}(PRIMAL, PARTIALS2)) == (PARTIALS == PARTIALS2) + @test isequal(FDNUM, FDNUM2) == (PARTIALS == PARTIALS2) + + @test (FDNUM == FDNUM2) == (PARTIALS == PARTIALS2) + @test (NESTED_FDNUM == NESTED_FDNUM2) == ((M_PARTIALS == M_PARTIALS2) && (NESTED_PARTIALS == NESTED_PARTIALS2)) + else + @test !isequal(FDNUM, FDNUM2) + + @test FDNUM != FDNUM2 + @test NESTED_FDNUM != NESTED_FDNUM2 + end @test isless(Dual{TestTag()}(1, PARTIALS), Dual{TestTag()}(2, PARTIALS2)) @test !(isless(Dual{TestTag()}(1, PARTIALS), Dual{TestTag()}(1, PARTIALS2))) diff --git a/test/runtests.jl b/test/runtests.jl index e97b40ee..a1ac67b3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,7 +1,7 @@ using ForwardDiff, Test, Random SEED = trunc(Int, time()) -println("Testing with Random.seed!($SEED)") +println("##### Random.seed!($SEED), on VERSION == $VERSION") Random.seed!(SEED) @testset "ForwardDiff.jl" begin @@ -53,5 +53,5 @@ Random.seed!(SEED) println("##### done (took $t seconds).") end end - println("##### Running all ForwardDiff tests took $(t0 - time()) seconds.") + println("##### Running all ForwardDiff tests took $(time() - t0) seconds.") end \ No newline at end of file From 94c47fc0e1538838442ec2419e16de08fa9c7075 Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Mon, 16 May 2022 14:41:41 -0400 Subject: [PATCH 18/22] v0.10.30 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 933ddb52..16158684 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ForwardDiff" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.11.0" +version = "0.10.30" [deps] CommonSubexpressions = "bbf7d656-a473-5ed7-a52c-81e309532950" From 8a3f5d3d1f666764ce812cc8c97741172c1fe00a Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Mon, 16 May 2022 14:45:56 -0400 Subject: [PATCH 19/22] rm some testsets --- test/DualTest.jl | 8 -------- 1 file changed, 8 deletions(-) diff --git a/test/DualTest.jl b/test/DualTest.jl index 455aef2c..7652e667 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -229,7 +229,6 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false # Predicates # #------------# - @testset "Predicates" begin @test ForwardDiff.isconstant(zero(FDNUM)) @test ForwardDiff.isconstant(one(FDNUM)) @@ -340,7 +339,6 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false @test isodd(Dual{TestTag()}(Dual{TestTag()}(1))) @test !(isodd(Dual{TestTag()}(Dual{TestTag()}(2)))) - end ######################## # Promotion/Conversion # ######################## @@ -414,7 +412,6 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false # Division # #----------# - @testset "Division" begin if M > 0 && N > 0 # Recall that FDNUM = Dual{TestTag()}(PRIMAL, PARTIALS) has N partials, @@ -435,11 +432,8 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false @test dual_isapprox(NESTED_FDNUM / PRIMAL, Dual{TestTag()}(value(NESTED_FDNUM) / PRIMAL, partials(NESTED_FDNUM) / PRIMAL)) @test dual_isapprox(PRIMAL / NESTED_FDNUM, Dual{TestTag()}(PRIMAL / value(NESTED_FDNUM), (-(PRIMAL) / value(NESTED_FDNUM)^2) * partials(NESTED_FDNUM))) - end - # Exponentiation # #----------------# - @testset "Exponentiation" begin # If V == Int, the LHS terms are Int's. Large inputs cause integer overflow # within the generic fallback of `isapprox`, resulting in a DomainError. @@ -454,7 +448,6 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false @test partials(NaNMath.pow(Dual{TestTag()}(-2.0, 1.0), Dual{TestTag()}(2.0, 0.0)), 1) == -4.0 - end ################################### # General Mathematical Operations # ################################### @@ -547,7 +540,6 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false # Special Cases # #---------------# - @testset "Special Cases" begin @test_broken dual_isapprox(hypot(FDNUM, FDNUM2, FDNUM), sqrt(2*(FDNUM^2) + FDNUM2^2)) @test_broken dual_isapprox(hypot(FDNUM, FDNUM2, FDNUM3), sqrt(FDNUM^2 + FDNUM2^2 + FDNUM3^2)) From c9c5361f966378fe60ac76def5c260542195b1ab Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Mon, 16 May 2022 22:09:12 -0400 Subject: [PATCH 20/22] fix some complex tests --- test/DualTest.jl | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/test/DualTest.jl b/test/DualTest.jl index 7652e667..b09f0594 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -464,7 +464,7 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false @test abs(NESTED_FDNUM) === NESTED_FDNUM if V != Int - for (M, f, arity) in DiffRules.diffrules(filter_modules = nothing) + @testset "$f" for (M, f, arity) in DiffRules.diffrules(filter_modules = nothing) if f in (:/, :rem2pi) continue # Skip these rules elseif !(isdefined(@__MODULE__, M) && isdefined(getfield(@__MODULE__, M), f)) @@ -524,10 +524,14 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false else @test dx isa Complex{<:Dual{TestTag()}} @test dy isa Complex{<:Dual{TestTag()}} - @test real(value(dx)) == real(actualval) - @test real(value(dy)) == real(actualval) - @test imag(value(dx)) == imag(actualval) - @test imag(value(dy)) == imag(actualval) + # @test real(value(dx)) == real(actualval) + # @test real(value(dy)) == real(actualval) + # @test imag(value(dx)) == imag(actualval) + # @test imag(value(dy)) == imag(actualval) + @test value(real(dx)) == real(actualval) + @test value(real(dy)) == real(actualval) + @test value(imag(dx)) == imag(actualval) + @test value(imag(dy)) == imag(actualval) @test partials(real(dx), 1) ≈ real(actualdx) nans=true @test partials(real(dy), 1) ≈ real(actualdy) nans=true @test partials(imag(dx), 1) ≈ imag(actualdx) nans=true From 3e82c328d9c2ed01e32234df06711b611602693f Mon Sep 17 00:00:00 2001 From: Michael Abbott <32575566+mcabbott@users.noreply.github.com> Date: Wed, 29 Jun 2022 20:47:48 -0600 Subject: [PATCH 21/22] tidy & comment, no real changes --- src/dual.jl | 27 ++++++++++++++------------- src/prelude.jl | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/dual.jl b/src/dual.jl index a8778538..1cf31731 100644 --- a/src/dual.jl +++ b/src/dual.jl @@ -384,9 +384,21 @@ for pred in UNARY_PREDICATES @eval Base.$(pred)(d::Dual) = $(pred)(value(d)) end -# BINARY_PREDICATES = Symbol[:isequal, :isless, :<, :>, :(==), :(!=), :(<=), :(>=)] # prelude.jl +# Before PR#481 this loop ran over this list: +# BINARY_PREDICATES = Symbol[:isequal, :isless, :<, :>, :(==), :(!=), :(<=), :(>=)] +# Not a minimal set, as Base defines some in terms of others. +for pred in [:isless, :<, :>, :(<=), :(>=)] + @eval begin + @define_binary_dual_op( + Base.$(pred), + $(pred)(value(x), value(y)), + $(pred)(value(x), y), + $(pred)(x, value(y)), + ) + end +end -Base.iszero(x::Dual) = iszero(value(x)) && iszero(partials(x)) +Base.iszero(x::Dual) = iszero(value(x)) && iszero(partials(x)) # shortcut, equivalent to x == zero(x) for pred in [:isequal, :(==)] @eval begin @@ -406,17 +418,6 @@ end (!=)(x, value(y)) || !iszero(partials(y)), ) -for pred in [:isless, :<, :>, :(<=), :(>=)] - @eval begin - @define_binary_dual_op( - Base.$(pred), - $(pred)(value(x), value(y)), - $(pred)(value(x), y), - $(pred)(x, value(y)), - ) - end -end - ######################## # Promotion/Conversion # ######################## diff --git a/src/prelude.jl b/src/prelude.jl index 1a5d0cfa..51643339 100644 --- a/src/prelude.jl +++ b/src/prelude.jl @@ -10,7 +10,7 @@ const AMBIGUOUS_TYPES = (AbstractFloat, Irrational, Integer, Rational, Real, Rou const UNARY_PREDICATES = Symbol[:isinf, :isnan, :isfinite, :iseven, :isodd, :isreal, :isinteger] -const BINARY_PREDICATES = Symbol[:isequal, :isless, :<, :>, :(==), :(!=), :(<=), :(>=)] +const DEFAULT_CHUNK_THRESHOLD = 12 struct Chunk{N} end From 5a5dbb6edf201e6a3fc20f376f2e876661590245 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Tue, 30 Aug 2022 14:18:10 +0200 Subject: [PATCH 22/22] Update Project.toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 16158684..ea59c5fa 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "ForwardDiff" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.30" +version = "0.10.33" [deps] CommonSubexpressions = "bbf7d656-a473-5ed7-a52c-81e309532950"