diff --git a/DifferentiationInterface/CHANGELOG.md b/DifferentiationInterface/CHANGELOG.md index e75526fbf..575d9cff7 100644 --- a/DifferentiationInterface/CHANGELOG.md +++ b/DifferentiationInterface/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.21...main) +### Added + +- New operators `value_gradient_and_hvp` and `value_gradient_and_hvp!`, which also return the primal value ([#1086](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/1086)) + +### Deprecated + +- `gradient_and_hvp` and `gradient_and_hvp!` are deprecated in favor of `value_gradient_and_hvp` and `value_gradient_and_hvp!` ([#1086](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/1086)) + ### Fixed - Speed up `pick_batchsize` when the batch size is only known at run time ([#1076](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/1076)) diff --git a/DifferentiationInterface/Project.toml b/DifferentiationInterface/Project.toml index a2a694816..594a3f743 100644 --- a/DifferentiationInterface/Project.toml +++ b/DifferentiationInterface/Project.toml @@ -1,6 +1,6 @@ name = "DifferentiationInterface" uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" -version = "0.7.21" +version = "0.7.22" authors = ["Guillaume Dalle", "Adrian Hill"] [deps] diff --git a/DifferentiationInterface/docs/src/api.md b/DifferentiationInterface/docs/src/api.md index eba5cee96..931566fa0 100644 --- a/DifferentiationInterface/docs/src/api.md +++ b/DifferentiationInterface/docs/src/api.md @@ -94,6 +94,8 @@ prepare_hvp prepare_hvp_same_point hvp hvp! +value_gradient_and_hvp +value_gradient_and_hvp! gradient_and_hvp gradient_and_hvp! ``` diff --git a/DifferentiationInterface/docs/src/explanation/operators.md b/DifferentiationInterface/docs/src/explanation/operators.md index 9664a03a4..ec5d9efa6 100644 --- a/DifferentiationInterface/docs/src/explanation/operators.md +++ b/DifferentiationInterface/docs/src/explanation/operators.md @@ -60,7 +60,7 @@ Several variants of each operator are defined: | [`jacobian`](@ref) | [`jacobian!`](@ref) | [`value_and_jacobian`](@ref) | [`value_and_jacobian!`](@ref) | | [`pushforward`](@ref) | [`pushforward!`](@ref) | [`value_and_pushforward`](@ref) | [`value_and_pushforward!`](@ref) | | [`pullback`](@ref) | [`pullback!`](@ref) | [`value_and_pullback`](@ref) | [`value_and_pullback!`](@ref) | -| [`hvp`](@ref) | [`hvp!`](@ref) | [`gradient_and_hvp`](@ref) | [`gradient_and_hvp!`](@ref) | +| [`hvp`](@ref) | [`hvp!`](@ref) | [`value_gradient_and_hvp`](@ref) | [`value_gradient_and_hvp!`](@ref) | ## Mutation and signatures diff --git a/DifferentiationInterface/ext/DifferentiationInterfaceFastDifferentiationExt/onearg.jl b/DifferentiationInterface/ext/DifferentiationInterfaceFastDifferentiationExt/onearg.jl index 316d1611c..5c6edfb6d 100644 --- a/DifferentiationInterface/ext/DifferentiationInterfaceFastDifferentiationExt/onearg.jl +++ b/DifferentiationInterface/ext/DifferentiationInterfaceFastDifferentiationExt/onearg.jl @@ -599,7 +599,7 @@ function DI.hvp!( return tg end -function DI.gradient_and_hvp( +function DI.value_gradient_and_hvp( f, prep::FastDifferentiationHVPPrep, backend::AutoFastDifferentiation, @@ -609,11 +609,11 @@ function DI.gradient_and_hvp( ) where {C} DI.check_prep(f, prep, backend, x, tx, contexts...) tg = DI.hvp(f, prep, backend, x, tx, contexts...) - grad = DI.gradient(f, prep.gradient_prep, backend, x, contexts...) - return grad, tg + y, grad = DI.value_and_gradient(f, prep.gradient_prep, backend, x, contexts...) + return y, grad, tg end -function DI.gradient_and_hvp!( +function DI.value_gradient_and_hvp!( f, grad, tg::NTuple, @@ -625,8 +625,8 @@ function DI.gradient_and_hvp!( ) where {C} DI.check_prep(f, prep, backend, x, tx, contexts...) DI.hvp!(f, tg, prep, backend, x, tx, contexts...) - DI.gradient!(f, grad, prep.gradient_prep, backend, x, contexts...) - return grad, tg + y, _ = DI.value_and_gradient!(f, grad, prep.gradient_prep, backend, x, contexts...) + return y, grad, tg end ## Hessian diff --git a/DifferentiationInterface/ext/DifferentiationInterfaceGTPSAExt/onearg.jl b/DifferentiationInterface/ext/DifferentiationInterfaceGTPSAExt/onearg.jl index d39f4747e..1d8ce650e 100644 --- a/DifferentiationInterface/ext/DifferentiationInterfaceGTPSAExt/onearg.jl +++ b/DifferentiationInterface/ext/DifferentiationInterfaceGTPSAExt/onearg.jl @@ -609,7 +609,7 @@ function DI.hvp!( return tg end -function DI.gradient_and_hvp( +function DI.value_gradient_and_hvp( f, prep::GTPSAOneArgHVPPrep, backend::AutoGTPSA{D}, @@ -619,7 +619,7 @@ function DI.gradient_and_hvp( ) where {D, C} DI.check_prep(f, prep, backend, x, tx, contexts...) grad = similar(x, eltype(prep.hess)) - DI.value_gradient_and_hessian!( + y, _, _ = DI.value_gradient_and_hessian!( f, grad, prep.hess, prep.hessprep, backend, x, contexts... ) tg = map(tx) do dx @@ -634,10 +634,10 @@ function DI.gradient_and_hvp( end return dg end - return grad, tg + return y, grad, tg end -function DI.gradient_and_hvp!( +function DI.value_gradient_and_hvp!( f, grad, tg, @@ -648,7 +648,7 @@ function DI.gradient_and_hvp!( contexts::Vararg{DI.Constant, C}, ) where {D, C} DI.check_prep(f, prep, backend, x, tx, contexts...) - DI.value_gradient_and_hessian!( + y, _, _ = DI.value_gradient_and_hessian!( f, grad, prep.hess, prep.hessprep, backend, x, contexts... ) for b in eachindex(tg, tx) @@ -662,5 +662,5 @@ function DI.gradient_and_hvp!( j += 1 end end - return grad, tg + return y, grad, tg end diff --git a/DifferentiationInterface/ext/DifferentiationInterfaceHyperHessiansExt/DifferentiationInterfaceHyperHessiansExt.jl b/DifferentiationInterface/ext/DifferentiationInterfaceHyperHessiansExt/DifferentiationInterfaceHyperHessiansExt.jl index b6426527f..ae8fd18f2 100644 --- a/DifferentiationInterface/ext/DifferentiationInterfaceHyperHessiansExt/DifferentiationInterfaceHyperHessiansExt.jl +++ b/DifferentiationInterface/ext/DifferentiationInterfaceHyperHessiansExt/DifferentiationInterfaceHyperHessiansExt.jl @@ -283,7 +283,7 @@ function DI.hvp!( return hvp!(tg, fc, x, tx, prep.cfg) end -function DI.gradient_and_hvp( +function DI.value_gradient_and_hvp( f, prep::HyperHessiansHVPPrep, backend::DI.AutoHyperHessians, @@ -295,10 +295,10 @@ function DI.gradient_and_hvp( contexts_prepared = translate_prepared(contexts, prep.contexts_prepared) fc = DI.fix_tail(f, contexts_prepared...) res = hvp_gradient_value(fc, x, tx, prep.cfg) - return res.gradient, res.hvp + return res.value, res.gradient, res.hvp end -function DI.gradient_and_hvp!( +function DI.value_gradient_and_hvp!( f, grad, tg::NTuple, @@ -311,8 +311,8 @@ function DI.gradient_and_hvp!( DI.check_prep(f, prep, backend, x, tx, contexts...) contexts_prepared = translate_prepared(contexts, prep.contexts_prepared) fc = DI.fix_tail(f, contexts_prepared...) - hvp_gradient_value!(tg, grad, fc, x, tx, prep.cfg) - return grad, tg + y = hvp_gradient_value!(tg, grad, fc, x, tx, prep.cfg) + return y, grad, tg end end diff --git a/DifferentiationInterface/ext/DifferentiationInterfaceMooncakeExt/second_order.jl b/DifferentiationInterface/ext/DifferentiationInterfaceMooncakeExt/second_order.jl index 942267727..0b9063968 100644 --- a/DifferentiationInterface/ext/DifferentiationInterfaceMooncakeExt/second_order.jl +++ b/DifferentiationInterface/ext/DifferentiationInterfaceMooncakeExt/second_order.jl @@ -13,7 +13,7 @@ function DI.prepare_hvp_nokwarg( return prep end -function DI.gradient_and_hvp( +function DI.value_gradient_and_hvp( f::F, prep::MooncakeHVPPrep{Y}, backend::AutoMooncakeForwardOverReverse, @@ -24,19 +24,19 @@ function DI.gradient_and_hvp( DI.check_prep(f, prep, backend, x, tx, contexts...) dx = only(tx) if isempty(contexts) - _, new_g, new_dg = value_and_hvp!!( + y, new_g, new_dg = value_and_hvp!!( prep.cache, f, (dx,), x ) else dall = (dx, map(zero_tangent_unwrap, contexts)...) - _, (new_g,), (new_dg,) = value_and_hvp!!( + y, (new_g,), (new_dg,) = value_and_hvp!!( prep.cache, f, dall, x, map(DI.unwrap, contexts)... ) end - return _copy_output(new_g), (_copy_output(new_dg),) + return y, _copy_output(new_g), (_copy_output(new_dg),) end -function DI.gradient_and_hvp( +function DI.value_gradient_and_hvp( f::F, prep::MooncakeHVPPrep{Y}, backend::AutoMooncakeForwardOverReverse, @@ -45,25 +45,25 @@ function DI.gradient_and_hvp( contexts::Vararg{DI.Context, C}, ) where {F, Y, C} DI.check_prep(f, prep, backend, x, tx, contexts...) - gs_and_tg = map(tx) do dx + ys_gs_and_tg = map(tx) do dx if isempty(contexts) - _, new_g, new_dg = value_and_hvp!!( + y, new_g, new_dg = value_and_hvp!!( prep.cache, f, dx, x ) else dall = (dx, map(zero_tangent_unwrap, contexts)...) - _, (new_g,), (new_dg,) = value_and_hvp!!( + y, (new_g,), (new_dg,) = value_and_hvp!!( prep.cache, f, dall, x, map(DI.unwrap, contexts)... ) end - _copy_output(new_g), _copy_output(new_dg) + y, _copy_output(new_g), _copy_output(new_dg) end - g = first(gs_and_tg[1]) - tg = map(last, gs_and_tg) - return g, tg + y, g, _ = ys_gs_and_tg[1] + tg = map(last, ys_gs_and_tg) + return y, g, tg end -function DI.gradient_and_hvp!( +function DI.value_gradient_and_hvp!( f::F, g, tg::NTuple, @@ -74,10 +74,10 @@ function DI.gradient_and_hvp!( contexts::Vararg{DI.Context, C}, ) where {F, C} DI.check_prep(f, prep, backend, x, tx, contexts...) - new_g, new_tg = DI.gradient_and_hvp(f, prep, backend, x, tx, contexts...) + y, new_g, new_tg = DI.value_gradient_and_hvp(f, prep, backend, x, tx, contexts...) copyto!(g, new_g) foreach(copyto!, tg, new_tg) - return g, tg + return y, g, tg end function DI.hvp( @@ -89,7 +89,7 @@ function DI.hvp( contexts::Vararg{DI.Context, C}, ) where {F, C} DI.check_prep(f, prep, backend, x, tx, contexts...) - return DI.gradient_and_hvp(f, prep, backend, x, tx, contexts...)[2] + return DI.value_gradient_and_hvp(f, prep, backend, x, tx, contexts...)[3] end function DI.hvp!( @@ -102,7 +102,7 @@ function DI.hvp!( contexts::Vararg{DI.Context, C}, ) where {F, C} DI.check_prep(f, prep, backend, x, tx, contexts...) - _, new_tg = DI.gradient_and_hvp(f, prep, backend, x, tx, contexts...) + _, _, new_tg = DI.value_gradient_and_hvp(f, prep, backend, x, tx, contexts...) foreach(copyto!, tg, new_tg) return tg end diff --git a/DifferentiationInterface/ext/DifferentiationInterfaceSymbolicsExt/onearg.jl b/DifferentiationInterface/ext/DifferentiationInterfaceSymbolicsExt/onearg.jl index 94079fcce..c0e8f361f 100644 --- a/DifferentiationInterface/ext/DifferentiationInterfaceSymbolicsExt/onearg.jl +++ b/DifferentiationInterface/ext/DifferentiationInterfaceSymbolicsExt/onearg.jl @@ -483,7 +483,7 @@ function DI.hvp!( return tg end -function DI.gradient_and_hvp( +function DI.value_gradient_and_hvp( f, prep::SymbolicsOneArgHVPPrep, backend::AutoSymbolics, @@ -493,11 +493,11 @@ function DI.gradient_and_hvp( ) where {C} DI.check_prep(f, prep, backend, x, tx, contexts...) tg = DI.hvp(f, prep, backend, x, tx, contexts...) - grad = DI.gradient(f, prep.gradient_prep, backend, x, contexts...) - return grad, tg + y, grad = DI.value_and_gradient(f, prep.gradient_prep, backend, x, contexts...) + return y, grad, tg end -function DI.gradient_and_hvp!( +function DI.value_gradient_and_hvp!( f, grad, tg::NTuple, @@ -509,8 +509,8 @@ function DI.gradient_and_hvp!( ) where {C} DI.check_prep(f, prep, backend, x, tx, contexts...) DI.hvp!(f, tg, prep, backend, x, tx, contexts...) - DI.gradient!(f, grad, prep.gradient_prep, backend, x, contexts...) - return grad, tg + y, _ = DI.value_and_gradient!(f, grad, prep.gradient_prep, backend, x, contexts...) + return y, grad, tg end ## Second derivative diff --git a/DifferentiationInterface/ext/DifferentiationInterfaceZygoteExt/DifferentiationInterfaceZygoteExt.jl b/DifferentiationInterface/ext/DifferentiationInterfaceZygoteExt/DifferentiationInterfaceZygoteExt.jl index cf2a0820b..852572f14 100644 --- a/DifferentiationInterface/ext/DifferentiationInterfaceZygoteExt/DifferentiationInterfaceZygoteExt.jl +++ b/DifferentiationInterface/ext/DifferentiationInterfaceZygoteExt/DifferentiationInterfaceZygoteExt.jl @@ -229,7 +229,7 @@ function DI.hvp!( ) end -function DI.gradient_and_hvp( +function DI.value_gradient_and_hvp( f, prep::ZygoteHVPPrep, backend::AutoZygote, @@ -238,12 +238,12 @@ function DI.gradient_and_hvp( contexts::Vararg{DI.Context, C}, ) where {C} DI.check_prep(f, prep, backend, x, tx, contexts...) - return DI.gradient_and_hvp( + return DI.value_gradient_and_hvp( f, prep.fd_prep, DI.SecondOrder(AutoForwardDiff(), backend), x, tx, contexts... ) end -function DI.gradient_and_hvp!( +function DI.value_gradient_and_hvp!( f, grad, tg::NTuple, @@ -254,7 +254,7 @@ function DI.gradient_and_hvp!( contexts::Vararg{DI.Context, C}, ) where {C} DI.check_prep(f, prep, backend, x, tx, contexts...) - return DI.gradient_and_hvp!( + return DI.value_gradient_and_hvp!( f, grad, tg, diff --git a/DifferentiationInterface/src/DifferentiationInterface.jl b/DifferentiationInterface/src/DifferentiationInterface.jl index 6f60b65df..6fc7f7e3b 100644 --- a/DifferentiationInterface/src/DifferentiationInterface.jl +++ b/DifferentiationInterface/src/DifferentiationInterface.jl @@ -92,7 +92,8 @@ export jacobian!, jacobian export second_derivative!, second_derivative export value_derivative_and_second_derivative, value_derivative_and_second_derivative! -export hvp!, hvp, gradient_and_hvp, gradient_and_hvp! +export hvp!, hvp, value_gradient_and_hvp, value_gradient_and_hvp! +export gradient_and_hvp, gradient_and_hvp! export hessian!, hessian export value_gradient_and_hessian, value_gradient_and_hessian! diff --git a/DifferentiationInterface/src/second_order/hvp.jl b/DifferentiationInterface/src/second_order/hvp.jl index 068781727..0e4cd4f7e 100644 --- a/DifferentiationInterface/src/second_order/hvp.jl +++ b/DifferentiationInterface/src/second_order/hvp.jl @@ -90,31 +90,65 @@ function hvp!( end """ - gradient_and_hvp(f, [prep,] backend, x, tx, [contexts...]) -> (grad, tg) + value_gradient_and_hvp(f, [prep,] backend, x, tx, [contexts...]) -> (y, grad, tg) -Compute the gradient and the Hessian-vector product of `f` at point `x` with a tuple of tangents `tx`. +Compute the value, the gradient and the Hessian-vector product of `f` at point `x` with a tuple of tangents `tx`. $(docstring_preparation_hint("hvp"; same_point = true)) """ -function gradient_and_hvp( +function value_gradient_and_hvp( f::F, backend::AbstractADType, x, tx, contexts::Vararg{Context, C} ) where {F, C} prep = prepare_hvp_nokwarg(Val(true), f, backend, x, tx, contexts...) - return gradient_and_hvp(f, prep, backend, x, tx, contexts...) + return value_gradient_and_hvp(f, prep, backend, x, tx, contexts...) end """ - gradient_and_hvp!(f, grad, tg, [prep,] backend, x, tx, [contexts...]) -> (grad, tg) + value_gradient_and_hvp!(f, grad, tg, [prep,] backend, x, tx, [contexts...]) -> (y, grad, tg) -Compute the gradient and the Hessian-vector product of `f` at point `x` with a tuple of tangents `tx`, overwriting `grad` and `tg`. +Compute the value, the gradient and the Hessian-vector product of `f` at point `x` with a tuple of tangents `tx`, overwriting `grad` and `tg`. $(docstring_preparation_hint("hvp"; same_point = true)) """ -function gradient_and_hvp!( +function value_gradient_and_hvp!( f::F, grad, tg, backend::AbstractADType, x, tx, contexts::Vararg{Context, C} ) where {F, C} prep = prepare_hvp_nokwarg(Val(true), f, backend, x, tx, contexts...) - return gradient_and_hvp!(f, grad, tg, prep, backend, x, tx, contexts...) + return value_gradient_and_hvp!(f, grad, tg, prep, backend, x, tx, contexts...) +end + +""" + gradient_and_hvp(f, [prep,] backend, x, tx, [contexts...]) -> (grad, tg) + +Compute the gradient and the Hessian-vector product of `f` at point `x` with a tuple of tangents `tx`. + +!!! warning "Deprecated" + + Use [`value_gradient_and_hvp`](@ref) instead. +""" +function gradient_and_hvp(f::F, args::Vararg{Any, N}) where {F, N} + Base.depwarn( + "`gradient_and_hvp` is deprecated, use `value_gradient_and_hvp` instead.", + :gradient_and_hvp, + ) + return Base.tail(value_gradient_and_hvp(f, args...)) +end + +""" + gradient_and_hvp!(f, grad, tg, [prep,] backend, x, tx, [contexts...]) -> (grad, tg) + +Compute the gradient and the Hessian-vector product of `f` at point `x` with a tuple of tangents `tx`, overwriting `grad` and `tg`. + +!!! warning "Deprecated" + + Use [`value_gradient_and_hvp!`](@ref) instead. +""" +function gradient_and_hvp!(f::F, args::Vararg{Any, N}) where {F, N} + Base.depwarn( + "`gradient_and_hvp!` is deprecated, use `value_gradient_and_hvp!` instead.", + :gradient_and_hvp!, + ) + return Base.tail(value_gradient_and_hvp!(f, args...)) end ## Preparation @@ -409,7 +443,7 @@ function _hvp_aux!( ) end -function gradient_and_hvp( +function value_gradient_and_hvp( f::F, prep::ForwardOverAnythingHVPPrep, backend::AbstractADType, @@ -427,12 +461,14 @@ function gradient_and_hvp( Constant(rewrap), contexts..., ) - return value_and_pushforward( + y = f(x, map(unwrap, contexts)...) + grad, tg = value_and_pushforward( shuffled_gradient, outer_pushforward_prep, outer(backend), x, tx, new_contexts... ) + return y, grad, tg end -function gradient_and_hvp!( +function value_gradient_and_hvp!( f::F, grad, tg::NTuple, @@ -443,9 +479,11 @@ function gradient_and_hvp!( contexts::Vararg{Context, C}, ) where {F, C} check_prep(f, prep, backend, x, tx, contexts...) - return _gradient_and_hvp_aux!( + y = f(x, map(unwrap, contexts)...) + _gradient_and_hvp_aux!( inplace_support(outer(backend)), f, grad, tg, prep, backend, x, tx, contexts... ) + return y, grad, tg end function _gradient_and_hvp_aux!( @@ -604,7 +642,7 @@ function hvp!( return tg end -function gradient_and_hvp( +function value_gradient_and_hvp( f::F, prep::ReverseOverForwardHVPPrep, backend::AbstractADType, @@ -614,11 +652,11 @@ function gradient_and_hvp( ) where {F, C} check_prep(f, prep, backend, x, tx, contexts...) tg = hvp(f, prep, backend, x, tx, contexts...) - grad = gradient(f, prep.gradient_prep, inner(backend), x, contexts...) - return grad, tg + y, grad = value_and_gradient(f, prep.gradient_prep, inner(backend), x, contexts...) + return y, grad, tg end -function gradient_and_hvp!( +function value_gradient_and_hvp!( f::F, grad, tg::NTuple, @@ -630,8 +668,8 @@ function gradient_and_hvp!( ) where {F, C} check_prep(f, prep, backend, x, tx, contexts...) hvp!(f, tg, prep, backend, x, tx, contexts...) - gradient!(f, grad, prep.gradient_prep, inner(backend), x, contexts...) - return grad, tg + y, _ = value_and_gradient!(f, grad, prep.gradient_prep, inner(backend), x, contexts...) + return y, grad, tg end ## Reverse over reverse @@ -762,7 +800,7 @@ function _hvp_aux!( ) end -function gradient_and_hvp( +function value_gradient_and_hvp( f::F, prep::ReverseOverReverseHVPPrep, backend::AbstractADType, @@ -776,12 +814,14 @@ function gradient_and_hvp( new_contexts = ( FunctionContext(f), Constant(inner(backend)), Constant(rewrap), contexts..., ) - return value_and_pullback( + y = f(x, map(unwrap, contexts)...) + grad, tg = value_and_pullback( shuffled_gradient, outer_pullback_prep, outer(backend), x, tx, new_contexts... ) + return y, grad, tg end -function gradient_and_hvp!( +function value_gradient_and_hvp!( f::F, grad, tg::NTuple, @@ -792,9 +832,11 @@ function gradient_and_hvp!( contexts::Vararg{Context, C}, ) where {F, C} check_prep(f, prep, backend, x, tx, contexts...) - return _gradient_and_hvp_aux!( + y = f(x, map(unwrap, contexts)...) + _gradient_and_hvp_aux!( inplace_support(outer(backend)), f, grad, tg, prep, backend, x, tx, contexts... ) + return y, grad, tg end function _gradient_and_hvp_aux!( diff --git a/DifferentiationInterface/test/Core/Internals/deprecations.jl b/DifferentiationInterface/test/Core/Internals/deprecations.jl new file mode 100644 index 000000000..7bee804a1 --- /dev/null +++ b/DifferentiationInterface/test/Core/Internals/deprecations.jl @@ -0,0 +1,29 @@ +using DifferentiationInterface +using DifferentiationInterface: AutoSimpleFiniteDiff +using Test + +@testset "gradient_and_hvp is deprecated" begin + f(x) = sum(abs2, x) + backend = AutoSimpleFiniteDiff() + x = [1.0, 2.0] + tx = ([1.0, 0.0], [0.0, 1.0]) + prep = prepare_hvp(f, backend, x, tx) + + y, grad, tg = value_gradient_and_hvp(f, prep, backend, x, tx) + @test y ≈ 5 + @test grad ≈ [2, 4] + @test all(isapprox.(tg, ([2, 0], [0, 2]); rtol = 1.0e-3)) + + grad_dep, tg_dep = @test_deprecated gradient_and_hvp(f, prep, backend, x, tx) + @test grad_dep ≈ grad + @test all(tg_dep .≈ tg) + + grad_in, tg_in = similar(x), map(similar, tx) + grad_dep!, tg_dep! = @test_deprecated gradient_and_hvp!( + f, grad_in, tg_in, prep, backend, x, tx + ) + @test grad_dep! === grad_in + @test tg_dep! === tg_in + @test grad_dep! ≈ grad + @test all(tg_dep! .≈ tg) +end diff --git a/DifferentiationInterfaceTest/CHANGELOG.md b/DifferentiationInterfaceTest/CHANGELOG.md index 46857eaa5..f6b3e136a 100644 --- a/DifferentiationInterfaceTest/CHANGELOG.md +++ b/DifferentiationInterfaceTest/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterfaceTest-v0.11.0...main) +### Changed + +- Test `value_gradient_and_hvp(!)` instead of the deprecated `gradient_and_hvp(!)`, which requires DifferentiationInterface v0.7.22 ([#1086](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/1086)) + ## [0.11.0](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterfaceTest-v0.10.4...DifferentiationInterfaceTest-v0.11.0) ### Changed diff --git a/DifferentiationInterfaceTest/Project.toml b/DifferentiationInterfaceTest/Project.toml index 5f4afe1b6..63f87b32c 100644 --- a/DifferentiationInterfaceTest/Project.toml +++ b/DifferentiationInterfaceTest/Project.toml @@ -39,7 +39,7 @@ AllocCheck = "0.2" Chairmarks = "1.2.1" ComponentArrays = "0.15" DataAPI = "1.16.0" -DifferentiationInterface = "0.7.7" +DifferentiationInterface = "0.7.22" DocStringExtensions = "0.8,0.9" ForwardDiff = "0.10.36,1" JET = "0.9,0.10,0.11,0.12" diff --git a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestChairmarksExt/DifferentiationInterfaceTestChairmarksExt.jl b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestChairmarksExt/DifferentiationInterfaceTestChairmarksExt.jl index 3be1a5357..010536ea2 100644 --- a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestChairmarksExt/DifferentiationInterfaceTestChairmarksExt.jl +++ b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestChairmarksExt/DifferentiationInterfaceTestChairmarksExt.jl @@ -47,8 +47,8 @@ using DifferentiationInterface: prepare!_hvp, hvp, hvp!, - gradient_and_hvp, - gradient_and_hvp!, + value_gradient_and_hvp, + value_gradient_and_hvp!, prepare_hessian, prepare!_hessian, hessian, diff --git a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestChairmarksExt/benchmark_eval.jl b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestChairmarksExt/benchmark_eval.jl index d679f58da..920cf30c5 100644 --- a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestChairmarksExt/benchmark_eval.jl +++ b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestChairmarksExt/benchmark_eval.jl @@ -5,7 +5,7 @@ for op in ALL_OPS elseif op == :hessian "value_gradient_and_" elseif op == :hvp - "gradient_and_" + "value_gradient_and_" else "value_and_" end diff --git a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestJETExt/DifferentiationInterfaceTestJETExt.jl b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestJETExt/DifferentiationInterfaceTestJETExt.jl index 40e06046a..a156464c9 100644 --- a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestJETExt/DifferentiationInterfaceTestJETExt.jl +++ b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestJETExt/DifferentiationInterfaceTestJETExt.jl @@ -45,8 +45,8 @@ using DifferentiationInterface: prepare!_hvp, hvp, hvp!, - gradient_and_hvp, - gradient_and_hvp!, + value_gradient_and_hvp, + value_gradient_and_hvp!, prepare_hessian, prepare!_hessian, hessian, diff --git a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestJETExt/type_stability_eval.jl b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestJETExt/type_stability_eval.jl index 949ea1855..9a7baf920 100644 --- a/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestJETExt/type_stability_eval.jl +++ b/DifferentiationInterfaceTest/ext/DifferentiationInterfaceTestJETExt/type_stability_eval.jl @@ -5,7 +5,7 @@ for op in ALL_OPS elseif op == :hessian "value_gradient_and_" elseif op == :hvp - "gradient_and_" + "value_gradient_and_" else "value_and_" end diff --git a/DifferentiationInterfaceTest/src/DifferentiationInterfaceTest.jl b/DifferentiationInterfaceTest/src/DifferentiationInterfaceTest.jl index c2fa68493..d623e97f4 100644 --- a/DifferentiationInterfaceTest/src/DifferentiationInterfaceTest.jl +++ b/DifferentiationInterfaceTest/src/DifferentiationInterfaceTest.jl @@ -62,8 +62,8 @@ using DifferentiationInterface: prepare!_hvp, hvp, hvp!, - gradient_and_hvp, - gradient_and_hvp!, + value_gradient_and_hvp, + value_gradient_and_hvp!, prepare_hessian, prepare!_hessian, hessian, diff --git a/DifferentiationInterfaceTest/src/tests/allocs_eval.jl b/DifferentiationInterfaceTest/src/tests/allocs_eval.jl index 2061d1872..ec8ab23fe 100644 --- a/DifferentiationInterfaceTest/src/tests/allocs_eval.jl +++ b/DifferentiationInterfaceTest/src/tests/allocs_eval.jl @@ -10,7 +10,7 @@ for op in ALL_OPS elseif op == :hessian "value_gradient_and_" elseif op == :hvp - "gradient_and_" + "value_gradient_and_" else "value_and_" end diff --git a/DifferentiationInterfaceTest/src/tests/correctness_eval.jl b/DifferentiationInterfaceTest/src/tests/correctness_eval.jl index ef76414b9..5142a7228 100644 --- a/DifferentiationInterfaceTest/src/tests/correctness_eval.jl +++ b/DifferentiationInterfaceTest/src/tests/correctness_eval.jl @@ -12,7 +12,7 @@ for op in ALL_OPS elseif op == :hessian "value_gradient_and_" elseif op == :hvp - "gradient_and_" + "value_gradient_and_" else "value_and_" end @@ -766,12 +766,14 @@ for op in ALL_OPS ((), (prep,), (prep_nostrict,), (prep_same,)) end foreach(preptup_cands_val) do preptup_val - res1_out1_val, res2_out1_val = $val_and_op( + y_out1_val, res1_out1_val, res2_out1_val = $val_and_op( f, preptup_val..., ba, x, t, contexts... ) - res1_out2_val, res2_out2_val = $val_and_op( + y_out2_val, res1_out2_val, res2_out2_val = $val_and_op( f, preptup_val..., ba, x, t, contexts... ) + @test y_out1_val ≈ scen.y + @test y_out2_val ≈ scen.y @test res1_out1_val ≈ scen.res1 @test res1_out2_val ≈ scen.res1 for b in eachindex(scen.res2) @@ -826,12 +828,14 @@ for op in ALL_OPS foreach(preptup_cands_val) do preptup_val res1_in1_val, res2_in1_val = mysimilar(res1), mysimilar(res2) res1_in2_val, res2_in2_val = mysimilar(res1), mysimilar(res2) - res1_out1_val, res2_out1_val = $val_and_op!( + y_out1_val, res1_out1_val, res2_out1_val = $val_and_op!( f, res1_in1_val, res2_in1_val, preptup_val..., ba, x, t, contexts... ) - res1_out2_val, res2_out2_val = $val_and_op!( + y_out2_val, res1_out2_val, res2_out2_val = $val_and_op!( f, res1_in2_val, res2_in2_val, preptup_val..., ba, x, t, contexts... ) + @test y_out1_val ≈ scen.y + @test y_out2_val ≈ scen.y @test res1_in1_val === res1_out1_val @test res1_in2_val === res1_out2_val @test res1_out1_val ≈ scen.res1 diff --git a/DifferentiationInterfaceTest/src/tests/prep_eval.jl b/DifferentiationInterfaceTest/src/tests/prep_eval.jl index 583bccd90..3a477835f 100644 --- a/DifferentiationInterfaceTest/src/tests/prep_eval.jl +++ b/DifferentiationInterfaceTest/src/tests/prep_eval.jl @@ -7,7 +7,7 @@ for op in ALL_OPS elseif op == :hessian "value_gradient_and_" elseif op == :hvp - "gradient_and_" + "value_gradient_and_" else "value_and_" end