From 197020709d71e98e9a231a5817bb7f6a7b26ff3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Fri, 25 Apr 2025 12:05:57 +0200 Subject: [PATCH 1/5] Add allocation tests for ReverseAD --- test/Nonlinear/ReverseAD.jl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/test/Nonlinear/ReverseAD.jl b/test/Nonlinear/ReverseAD.jl index 43fbb28b4f..f106d1fad2 100644 --- a/test/Nonlinear/ReverseAD.jl +++ b/test/Nonlinear/ReverseAD.jl @@ -138,19 +138,28 @@ function test_objective_quadratic_multivariate_subexpressions() evaluator = Nonlinear.Evaluator(model, Nonlinear.SparseReverseMode(), [x, y]) MOI.initialize(evaluator, [:Grad, :Jac, :Hess]) - @test MOI.eval_objective(evaluator, [1.2, 2.3]) == 1.2^2 + 1.2 * 2.3 + 2.3^2 + val = [1.2, 2.3] + @test MOI.eval_objective(evaluator, val) == 1.2^2 + 1.2 * 2.3 + 2.3^2 + @test 0 == @allocated MOI.eval_objective(evaluator, val) g = [NaN, NaN] - MOI.eval_objective_gradient(evaluator, g, [1.2, 2.3]) + MOI.eval_objective_gradient(evaluator, g, val) @test g == [2 * 1.2 + 2.3, 1.2 + 2 * 2.3] + @test 0 == @allocated MOI.eval_objective_gradient(evaluator, g, val) @test MOI.hessian_objective_structure(evaluator) == [(1, 1), (2, 2), (2, 1)] + MOI.hessian_objective_structure(evaluator) == [(1, 1), (2, 2), (2, 1)] H = [NaN, NaN, NaN] - MOI.eval_hessian_objective(evaluator, H, [1.2, 2.3]) + MOI.eval_hessian_objective(evaluator, H, val) @test H == [2.0, 2.0, 1.0] + @test evaluator.backend.max_chunk == 2 + # The call of `_eval_hessian_inner` from `_eval_hessian` needs dynamic dispatch for `Val(chunk)` so it allocates. + # We call directly `_eval_hessian_inner` to check that the rest does not allocates. + @test @allocated MOI.Nonlinear.ReverseAD._eval_hessian_inner(evaluator.backend, evaluator.backend.objective, H, 1.0, 0, Val(2)) @test MOI.hessian_lagrangian_structure(evaluator) == [(1, 1), (2, 2), (2, 1)] H = [NaN, NaN, NaN] - MOI.eval_hessian_lagrangian(evaluator, H, [1.2, 2.3], 1.5, Float64[]) + MOI.eval_hessian_lagrangian(evaluator, H, val, 1.5, Float64[]) @test H == 1.5 .* [2.0, 2.0, 1.0] + MOI.eval_hessian_lagrangian(evaluator, H, val, 1.5, Float64[]) v = [0.3, 0.4] hv = [NaN, NaN] MOI.eval_hessian_lagrangian_product( From b0e4e046c562658a1287af4fac57c6308c189cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sat, 26 Apr 2025 09:28:27 +0200 Subject: [PATCH 2/5] Add allocation tests --- test/Nonlinear/ReverseAD.jl | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/test/Nonlinear/ReverseAD.jl b/test/Nonlinear/ReverseAD.jl index f106d1fad2..7a149afdae 100644 --- a/test/Nonlinear/ReverseAD.jl +++ b/test/Nonlinear/ReverseAD.jl @@ -153,24 +153,18 @@ function test_objective_quadratic_multivariate_subexpressions() @test evaluator.backend.max_chunk == 2 # The call of `_eval_hessian_inner` from `_eval_hessian` needs dynamic dispatch for `Val(chunk)` so it allocates. # We call directly `_eval_hessian_inner` to check that the rest does not allocates. - @test @allocated MOI.Nonlinear.ReverseAD._eval_hessian_inner(evaluator.backend, evaluator.backend.objective, H, 1.0, 0, Val(2)) + @test 0 == @allocated MOI.Nonlinear.ReverseAD._eval_hessian_inner(evaluator.backend, evaluator.backend.objective, H, 1.0, 0, Val(2)) @test MOI.hessian_lagrangian_structure(evaluator) == [(1, 1), (2, 2), (2, 1)] H = [NaN, NaN, NaN] - MOI.eval_hessian_lagrangian(evaluator, H, val, 1.5, Float64[]) + μ = Float64[] + MOI.eval_hessian_lagrangian(evaluator, H, val, 1.5, μ) @test H == 1.5 .* [2.0, 2.0, 1.0] - MOI.eval_hessian_lagrangian(evaluator, H, val, 1.5, Float64[]) v = [0.3, 0.4] hv = [NaN, NaN] - MOI.eval_hessian_lagrangian_product( - evaluator, - hv, - [1.2, 2.3], - v, - 1.5, - Float64[], - ) + MOI.eval_hessian_lagrangian_product(evaluator, hv, val, v, 1.5, μ) @test hv ≈ 1.5 .* [2 1; 1 2] * v + @test 0 == @allocated MOI.eval_hessian_lagrangian_product(evaluator, hv, val, v, 1.5, μ) return end From 9ae2f3cccda3d25e263779a34801a13370252ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sat, 26 Apr 2025 09:28:38 +0200 Subject: [PATCH 3/5] Fix format --- test/Nonlinear/ReverseAD.jl | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/test/Nonlinear/ReverseAD.jl b/test/Nonlinear/ReverseAD.jl index 7a149afdae..6f89cb4a9d 100644 --- a/test/Nonlinear/ReverseAD.jl +++ b/test/Nonlinear/ReverseAD.jl @@ -153,7 +153,14 @@ function test_objective_quadratic_multivariate_subexpressions() @test evaluator.backend.max_chunk == 2 # The call of `_eval_hessian_inner` from `_eval_hessian` needs dynamic dispatch for `Val(chunk)` so it allocates. # We call directly `_eval_hessian_inner` to check that the rest does not allocates. - @test 0 == @allocated MOI.Nonlinear.ReverseAD._eval_hessian_inner(evaluator.backend, evaluator.backend.objective, H, 1.0, 0, Val(2)) + @test 0 == @allocated MOI.Nonlinear.ReverseAD._eval_hessian_inner( + evaluator.backend, + evaluator.backend.objective, + H, + 1.0, + 0, + Val(2), + ) @test MOI.hessian_lagrangian_structure(evaluator) == [(1, 1), (2, 2), (2, 1)] H = [NaN, NaN, NaN] @@ -164,7 +171,14 @@ function test_objective_quadratic_multivariate_subexpressions() hv = [NaN, NaN] MOI.eval_hessian_lagrangian_product(evaluator, hv, val, v, 1.5, μ) @test hv ≈ 1.5 .* [2 1; 1 2] * v - @test 0 == @allocated MOI.eval_hessian_lagrangian_product(evaluator, hv, val, v, 1.5, μ) + @test 0 == @allocated MOI.eval_hessian_lagrangian_product( + evaluator, + hv, + val, + v, + 1.5, + μ, + ) return end From 9e982b4dd89e8253179f18aee2de2e19b33bf940 Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Mon, 28 Apr 2025 10:28:08 +1200 Subject: [PATCH 4/5] Update test/Nonlinear/ReverseAD.jl --- test/Nonlinear/ReverseAD.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Nonlinear/ReverseAD.jl b/test/Nonlinear/ReverseAD.jl index 6f89cb4a9d..1027dd316e 100644 --- a/test/Nonlinear/ReverseAD.jl +++ b/test/Nonlinear/ReverseAD.jl @@ -146,7 +146,7 @@ function test_objective_quadratic_multivariate_subexpressions() @test g == [2 * 1.2 + 2.3, 1.2 + 2 * 2.3] @test 0 == @allocated MOI.eval_objective_gradient(evaluator, g, val) @test MOI.hessian_objective_structure(evaluator) == [(1, 1), (2, 2), (2, 1)] - MOI.hessian_objective_structure(evaluator) == [(1, 1), (2, 2), (2, 1)] + @test MOI.hessian_objective_structure(evaluator) == [(1, 1), (2, 2), (2, 1)] H = [NaN, NaN, NaN] MOI.eval_hessian_objective(evaluator, H, val) @test H == [2.0, 2.0, 1.0] From efe4e3791e8231fa7687341f5087f8f03f19dd71 Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Mon, 28 Apr 2025 10:28:45 +1200 Subject: [PATCH 5/5] Update test/Nonlinear/ReverseAD.jl --- test/Nonlinear/ReverseAD.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Nonlinear/ReverseAD.jl b/test/Nonlinear/ReverseAD.jl index 1027dd316e..18f61b7114 100644 --- a/test/Nonlinear/ReverseAD.jl +++ b/test/Nonlinear/ReverseAD.jl @@ -146,7 +146,6 @@ function test_objective_quadratic_multivariate_subexpressions() @test g == [2 * 1.2 + 2.3, 1.2 + 2 * 2.3] @test 0 == @allocated MOI.eval_objective_gradient(evaluator, g, val) @test MOI.hessian_objective_structure(evaluator) == [(1, 1), (2, 2), (2, 1)] - @test MOI.hessian_objective_structure(evaluator) == [(1, 1), (2, 2), (2, 1)] H = [NaN, NaN, NaN] MOI.eval_hessian_objective(evaluator, H, val) @test H == [2.0, 2.0, 1.0]