diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 391d16c2..48cb664a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,7 @@ jobs: - 'min' - 'lts' - '1' + - 'pre' os: - ubuntu-latest - windows-latest diff --git a/Project.toml b/Project.toml index f631c512..02a1eb5b 100644 --- a/Project.toml +++ b/Project.toml @@ -27,6 +27,7 @@ DiffResults = "1.1" DiffRules = "1.4" DiffTests = "0.1" IrrationalConstants = "0.1, 0.2" +JET = "0.9, 0.10" LogExpFunctions = "0.3" NaNMath = "1" Preferences = "1" @@ -39,9 +40,10 @@ Calculus = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" DiffTests = "de460e47-3fe3-5279-bb4a-814414816d5d" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" IrrationalConstants = "92d709cd-6900-40b7-9082-c6be49f344b6" +JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Calculus", "DiffTests", "IrrationalConstants", "SparseArrays", "StaticArrays", "Test", "InteractiveUtils"] +test = ["Calculus", "DiffTests", "IrrationalConstants", "JET", "SparseArrays", "StaticArrays", "Test", "InteractiveUtils"] diff --git a/src/config.jl b/src/config.jl index d561b4fd..3c6c97e3 100644 --- a/src/config.jl +++ b/src/config.jl @@ -29,7 +29,7 @@ struct InvalidTagException{E,O} <: Exception end Base.showerror(io::IO, e::InvalidTagException{E,O}) where {E,O} = - print(io, "Invalid Tag object:\n Expected $E,\n Observed $O.") + print(io, "Invalid Tag object:\n Expected ", E, ",\n Observed ", O, ".") checktag(::Type{Tag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT,VT,F,V} = throw(InvalidTagException{Tag{F,V},Tag{FT,VT}}()) diff --git a/src/dual.jl b/src/dual.jl index f9b83c4e..c070644f 100644 --- a/src/dual.jl +++ b/src/dual.jl @@ -35,11 +35,10 @@ struct DualMismatchError{A,B} <: Exception end Base.showerror(io::IO, e::DualMismatchError{A,B}) where {A,B} = - print(io, "Cannot determine ordering of Dual tags $(e.a) and $(e.b)") + print(io, "Cannot determine ordering of Dual tags ", e.a, " and ", e.b) @noinline function throw_cannot_dual(V::Type) - throw(ArgumentError("Cannot create a dual over scalar type $V." * - " If the type behaves as a scalar, define ForwardDiff.can_dual(::Type{$V}) = true.")) + throw(ArgumentError(lazy"Cannot create a dual over scalar type $V. If the type behaves as a scalar, define ForwardDiff.can_dual(::Type{$V}) = true.")) end """ diff --git a/src/gradient.jl b/src/gradient.jl index e6e56e46..0832d354 100644 --- a/src/gradient.jl +++ b/src/gradient.jl @@ -113,7 +113,9 @@ end function chunk_mode_gradient_expr(result_definition::Expr) return quote - @assert structural_length(x) >= N "chunk size cannot be greater than ForwardDiff.structural_length(x) ($(N) > $(structural_length(x)))" + if structural_length(x) < N + throw(ArgumentError(lazy"chunk size cannot be greater than ForwardDiff.structural_length(x) ($(N) > $(structural_length(x)))")) + end # precalculate loop bounds xlen = structural_length(x) diff --git a/src/jacobian.jl b/src/jacobian.jl index 83e21ea5..b12142a3 100644 --- a/src/jacobian.jl +++ b/src/jacobian.jl @@ -169,7 +169,9 @@ const JACOBIAN_ERROR = DimensionMismatch("jacobian(f, x) expects that f(x) is an function jacobian_chunk_mode_expr(work_array_definition::Expr, compute_ydual::Expr, result_definition::Expr, y_definition::Expr) return quote - @assert structural_length(x) >= N "chunk size cannot be greater than ForwardDiff.structural_length(x) ($(N) > $(structural_length(x)))" + if structural_length(x) < N + throw(ArgumentError(lazy"chunk size cannot be greater than ForwardDiff.structural_length(x) ($(N) > $(structural_length(x)))")) + end # precalculate loop bounds xlen = structural_length(x) diff --git a/test/AllocationsTest.jl b/test/AllocationsTest.jl index 9b20fb60..9e7c38be 100644 --- a/test/AllocationsTest.jl +++ b/test/AllocationsTest.jl @@ -13,28 +13,19 @@ convert_test_574() = convert(ForwardDiff.Dual{Nothing,ForwardDiff.Dual{Nothing,F seeds = cfg.seeds seed = cfg.seeds[1] - alloc = @allocated ForwardDiff.seed!(duals, x, seeds) - alloc = @allocated ForwardDiff.seed!(duals, x, seeds) - @test alloc == 0 - - alloc = @allocated ForwardDiff.seed!(duals, x, seed) - alloc = @allocated ForwardDiff.seed!(duals, x, seed) - @test alloc == 0 - - index = 1 - alloc = @allocated ForwardDiff.seed!(duals, x, index, seeds) - alloc = @allocated ForwardDiff.seed!(duals, x, index, seeds) - @test alloc == 0 - - index = 1 - alloc = @allocated ForwardDiff.seed!(duals, x, index, seed) - alloc = @allocated ForwardDiff.seed!(duals, x, index, seed) - @test alloc == 0 - - alloc = @allocated convert_test_574() - alloc = @allocated convert_test_574() - @test alloc == 0 - + allocs_seed!(args...) = @allocated ForwardDiff.seed!(args...) + allocs_seed!(duals, x, seeds) + @test iszero(allocs_seed!(duals, x, seeds)) + allocs_seed!(duals, x, seed) + @test iszero(allocs_seed!(duals, x, seed)) + allocs_seed!(duals, x, 1, seeds) + @test iszero(allocs_seed!(duals, x, 1, seeds)) + allocs_seed!(duals, x, 1, seed) + @test iszero(allocs_seed!(duals, x, 1, seed)) + + allocs_convert_test_574() = @allocated convert_test_574() + allocs_convert_test_574() + @test iszero(allocs_convert_test_574()) end end diff --git a/test/DualTest.jl b/test/DualTest.jl index fa26bfd3..8ca5d2b1 100644 --- a/test/DualTest.jl +++ b/test/DualTest.jl @@ -507,8 +507,7 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false @eval begin x = rand() + $modifier dx = @inferred $M.$f(Dual{TestTag}(x, one(x))) - actualval = $M.$f(x) - @assert actualval isa Real || actualval isa Complex + actualval = $M.$f(x)::Union{Real,Complex} if actualval isa Real @test dx isa Dual{TestTag} @test value(dx) == actualval @@ -536,8 +535,7 @@ ForwardDiff.:≺(::Type{OuterTestTag}, ::Type{TestTag}) = false dy = @inferred $M.$f(x, Dual{TestTag}(y, one(y))) actualdx = $(derivs[1]) actualdy = $(derivs[2]) - actualval = $M.$f(x, y) - @assert actualval isa Real || actualval isa Complex + actualval = $M.$f(x, y)::Union{Real,Complex} if actualval isa Real @test dx isa Dual{TestTag} @test dy isa Dual{TestTag} diff --git a/test/QATest.jl b/test/QATest.jl new file mode 100644 index 00000000..860ccdb0 --- /dev/null +++ b/test/QATest.jl @@ -0,0 +1,16 @@ +module QATest + +using ForwardDiff +using Test + +using JET: @test_opt + +@testset "JET" begin + # issue #778 + @test_opt ForwardDiff.derivative(identity, 1.0) + @test_opt ForwardDiff.gradient(only, [1.0], ForwardDiff.GradientConfig(only, [1.0], ForwardDiff.Chunk{1}())) + @test_opt ForwardDiff.jacobian(identity, [1.0], ForwardDiff.JacobianConfig(identity, [1.0], ForwardDiff.Chunk{1}())) + @test_opt ForwardDiff.hessian(only, [1.0], ForwardDiff.HessianConfig(only, [1.0], ForwardDiff.Chunk{1}())) +end + +end # module diff --git a/test/runtests.jl b/test/runtests.jl index e440af65..01f6f62e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -51,5 +51,10 @@ Random.seed!(SEED) t = @elapsed include("AllocationsTest.jl") println("##### done (took $t seconds).") end + @testset "QA" begin + println("##### QA testing...") + t = @elapsed include("QATest.jl") + println("##### done (took ", t, " seconds).") + end println("##### Running all ForwardDiff tests took $(time() - t0) seconds.") end