@@ -671,7 +671,6 @@ function test_diff_errors_POI()
671
671
return
672
672
end
673
673
674
-
675
674
function test_diff_errors ()
676
675
model = Model (
677
676
() -> DiffOpt. diff_optimizer (
@@ -719,7 +718,55 @@ function test_diff_errors()
719
718
DiffOpt. ReverseConstraintFunction (),
720
719
cons,
721
720
)
721
+ return
722
+ end
723
+
724
+ function is_empty (cache:: DiffOpt.InputCache )
725
+ return isempty (cache. dx) &&
726
+ isempty (cache. scalar_constraints) &&
727
+ isempty (cache. vector_constraints) &&
728
+ cache. objective === nothing
729
+ end
730
+
731
+ # Credit to @klamike
732
+ function test_empty_cache ()
733
+ m = Model (
734
+ () -> DiffOpt. diff_optimizer (
735
+ HiGHS. Optimizer;
736
+ with_parametric_opt_interface = true ,
737
+ ),
738
+ )
739
+ @variable (m, x)
740
+ @variable (m, p ∈ Parameter (1.0 ))
741
+ @variable (m, q ∈ Parameter (2.0 ))
742
+ @constraint (m, x ≥ p)
743
+ @constraint (m, x ≥ q)
744
+ @objective (m, Min, x)
745
+ optimize! (m)
746
+ @assert is_solved_and_feasible (m)
747
+
748
+ function get_sensitivity (m, xᵢ, pᵢ)
749
+ DiffOpt. empty_input_sensitivities! (m)
750
+ @test is_empty (unsafe_backend (m). optimizer. input_cache)
751
+ if ! isnothing (unsafe_backend (m). optimizer. diff) &&
752
+ ! isnothing (unsafe_backend (m). optimizer. diff. model. input_cache)
753
+ @test is_empty (unsafe_backend (m). optimizer. diff. model. input_cache)
754
+ end
755
+ MOI. set (
756
+ m,
757
+ DiffOpt. ForwardConstraintSet (),
758
+ ParameterRef (pᵢ),
759
+ Parameter (1.0 ),
760
+ )
761
+ DiffOpt. forward_differentiate! (m)
762
+ return MOI. get (m, DiffOpt. ForwardVariablePrimal (), xᵢ)
763
+ end
722
764
765
+ sp1 = get_sensitivity (m, x, p)
766
+ sp2 = get_sensitivity (m, x, q)
767
+ sp3 = get_sensitivity (m, x, p)
768
+ @test sp1 ≈ sp3
769
+ @test sp2 ≠ sp3
723
770
return
724
771
end
725
772
0 commit comments