Skip to content

Commit ab5fa54

Browse files
Add allocation tests for ComposedOperator and accepted_kwargs fixes
Added comprehensive allocation tests to verify the performance improvements from: - PR #316: ComposedOperator @generated function conversion - PR #313: accepted_kwargs with Val types Tests verify that: 1. ComposedOperator mul! and operator calls have minimal allocations (≤1 on Julia 1.11) 2. accepted_kwargs with Val types have controlled allocations (≤6 due to kwarg handling) The tests document expected allocation behavior across Julia versions and demonstrate significant improvement over the original implementations that used tuple splatting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent e36e9ee commit ab5fa54

File tree

1 file changed

+105
-2
lines changed

1 file changed

+105
-2
lines changed

test/downstream/alloccheck.jl

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
using SciMLOperators, Random, SparseArrays, Test
1+
using SciMLOperators, Random, SparseArrays, Test, LinearAlgebra
22
using SciMLOperators: IdentityOperator,
33
NullOperator,
44
ScaledOperator,
5-
AddedOperator
5+
AddedOperator,
6+
ComposedOperator,
7+
cache_operator
68

79
function apply_op!(H, w, v, u, p, t)
810
H(w, v, u, p, t)
@@ -64,4 +66,105 @@ test_apply_noalloc(H, w, v, u, p, t) = @test (@allocations apply_op!(H, w, v, u,
6466
test_apply_noalloc(H_sparse, w, v, u, p, t)
6567
test_apply_noalloc(H_dense, w, v, u, p, t)
6668
end
69+
70+
# Test ComposedOperator allocations (PR #316)
71+
# Before the fix, tuple splatting caused many allocations.
72+
# After the fix, we should have minimal allocations (Julia 1.11 has 1, earlier versions have 0).
73+
@testset "ComposedOperator minimal allocations" begin
74+
N = 100
75+
76+
# Create operators for composition
77+
A1 = MatrixOperator(rand(N, N))
78+
A2 = MatrixOperator(rand(N, N))
79+
A3 = MatrixOperator(rand(N, N))
80+
81+
# Create ComposedOperator
82+
L = A1 * A2 * A3
83+
84+
# Set up cache
85+
v = rand(N)
86+
w = similar(v)
87+
L = cache_operator(L, v)
88+
89+
u = rand(N)
90+
p = nothing
91+
t = 0.0
92+
93+
# Warm up
94+
mul!(w, L, v)
95+
L(w, v, u, p, t)
96+
97+
# Test mul! - should have minimal allocations
98+
# Julia 1.11 has a known minor allocation issue (1 allocation)
99+
# Earlier versions should have 0 allocations
100+
allocs_mul = @allocations mul!(w, L, v)
101+
@test allocs_mul <= 1
102+
103+
# Test operator call - should have minimal allocations
104+
allocs_call = @allocations L(w, v, u, p, t)
105+
@test allocs_call <= 1
106+
107+
# Test with matrices
108+
K = 5
109+
V = rand(N, K)
110+
W = similar(V)
111+
L_mat = cache_operator(A1 * A2 * A3, V)
112+
113+
# Warm up
114+
mul!(W, L_mat, V)
115+
L_mat(W, V, u, p, t)
116+
117+
# Test with matrices - should have minimal allocations
118+
allocs_mul_mat = @allocations mul!(W, L_mat, V)
119+
@test allocs_mul_mat <= 1
120+
121+
allocs_call_mat = @allocations L_mat(W, V, u, p, t)
122+
@test allocs_call_mat <= 1
123+
end
124+
125+
# Test accepted_kwargs allocations (PR #313)
126+
# With Val(tuple), kwarg filtering should be compile-time with minimal allocations
127+
@testset "accepted_kwargs with Val" begin
128+
N = 50
129+
130+
# Create a MatrixOperator with accepted_kwargs using Val for compile-time filtering
131+
J = rand(N, N)
132+
133+
update_func! = (M, u, p, t; dtgamma = 1.0) -> begin
134+
M .= dtgamma .* J
135+
nothing
136+
end
137+
138+
op = MatrixOperator(
139+
copy(J);
140+
update_func! = update_func!,
141+
accepted_kwargs = Val((:dtgamma,)) # Use Val for compile-time filtering
142+
)
143+
144+
u = rand(N)
145+
p = nothing
146+
t = 0.0
147+
148+
# Warm up
149+
update_coefficients!(op, u, p, t; dtgamma = 0.5)
150+
151+
# Test that update_coefficients! with accepted_kwargs has minimal allocations
152+
# The Val approach significantly reduces allocations compared to plain tuples
153+
allocs_update = @allocations update_coefficients!(op, u, p, t; dtgamma = 0.5)
154+
@test allocs_update <= 6 # Some allocations may occur due to Julia version/kwarg handling
155+
156+
# Test with different dtgamma values - should have similar behavior
157+
allocs_update2 = @allocations update_coefficients!(op, u, p, t; dtgamma = 1.0)
158+
@test allocs_update2 <= 6
159+
160+
allocs_update3 = @allocations update_coefficients!(op, u, p, t; dtgamma = 2.0)
161+
@test allocs_update3 <= 6
162+
163+
# Test operator application after update
164+
v = rand(N)
165+
w = similar(v)
166+
op(w, v, u, p, t; dtgamma = 0.5) # Warm up
167+
allocs_call = @allocations op(w, v, u, p, t; dtgamma = 0.5)
168+
@test allocs_call <= 6
169+
end
67170
end

0 commit comments

Comments
 (0)