Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 29 additions & 84 deletions test/alloc_tests.jl
Original file line number Diff line number Diff line change
@@ -1,48 +1,36 @@
using AllocCheck
using BenchmarkTools
using FastAlmostBandedMatrices
using FastAlmostBandedMatrices: DisjointRange
using ArrayLayouts: colsupport, rowsupport
using Test

# Allocation freedom is verified with `AllocCheck.check_allocs`, which statically
# proves the absence of any allocating code path for the given argument types.
# This is immune to the first-call compilation and global-scope boxing noise that
# `@allocated` picks up on newer Julia versions, so it directly tests the intended
# invariant (the operation never allocates) rather than a single runtime sample.

getidx(A, i...) = A[i...]
setidx!(A, v, i...) = (A[i...] = v; nothing)
function sumiter(d)
s = zero(eltype(d))
for x in d
s += x
end
return s
end

@testset "Allocation Tests" begin
@testset "DisjointRange - Zero Allocations" begin
# Test that DisjointRange operations don't allocate
r1 = Base.OneTo(5)
r2 = 10:15
dr = DisjointRange(r1, r2)

# Test length
allocs = @allocated length(dr)
@test allocs == 0

# Test getindex
allocs = @allocated dr[3]
@test allocs == 0

allocs = @allocated dr[8]
@test allocs == 0

# Test first/last
allocs = @allocated first(dr)
@test allocs == 0

allocs = @allocated last(dr)
@test allocs == 0

# Test iteration (after warmup)
sum_test = 0
for x in dr
sum_test += x
end
allocs = @allocated begin
s = 0
for x in dr
s += x
end
s
end
@test allocs == 0
@test isempty(check_allocs(length, (typeof(dr),)))
@test isempty(check_allocs(getidx, (typeof(dr), Int)))
@test isempty(check_allocs(first, (typeof(dr),)))
@test isempty(check_allocs(last, (typeof(dr),)))
@test isempty(check_allocs(sumiter, (typeof(dr),)))
end

@testset "colsupport - Zero Allocations" begin
Expand All @@ -52,17 +40,9 @@ using Test
F = rand(Float64, m, n)
A = AlmostBandedMatrix(B, F)

# Warmup
colsupport(A, 5)
colsupport(A, 50)

# Test colsupport for j <= l+u (should return OneTo, no allocation)
allocs = @allocated colsupport(A, 5)
@test allocs == 0

# Test colsupport for j > l+u (now returns DisjointRange instead of vcat)
allocs = @allocated colsupport(A, 50)
@test allocs == 0
# colsupport returns OneTo for j <= l+u and a DisjointRange otherwise; both
# branches must be allocation-free.
@test isempty(check_allocs(colsupport, (typeof(A), Int)))
end

@testset "rowsupport - Zero Allocations" begin
Expand All @@ -72,16 +52,7 @@ using Test
F = rand(Float64, m, n)
A = AlmostBandedMatrix(B, F)

# Warmup
rowsupport(A, 1)
rowsupport(A, 50)

# Test rowsupport (always returns UnitRange, no allocation)
allocs = @allocated rowsupport(A, 1)
@test allocs == 0

allocs = @allocated rowsupport(A, 50)
@test allocs == 0
@test isempty(check_allocs(rowsupport, (typeof(A), Int)))
end

@testset "getindex/setindex! - Zero Allocations" begin
Expand All @@ -91,25 +62,8 @@ using Test
F = rand(Float64, m, n)
A = AlmostBandedMatrix(B, F)

# Warmup
_ = A[50, 50]
A[50, 50] = 1.0

# Test getindex
allocs = @allocated A[50, 50]
@test allocs == 0

# Test setindex! in band part
allocs = @allocated A[50, 50] = 2.0
@test allocs == 0

# Test setindex! in fill part
allocs = @allocated A[1, 50] = 3.0
@test allocs == 0

# Test setindex! in overlapping part
allocs = @allocated A[1, 1] = 4.0
@test allocs == 0
@test isempty(check_allocs(getidx, (typeof(A), Int, Int)))
@test isempty(check_allocs(setidx!, (typeof(A), Float64, Int, Int)))
end

@testset "bandpart/fillpart - Zero Allocations" begin
Expand All @@ -119,16 +73,7 @@ using Test
F = rand(Float64, m, n)
A = AlmostBandedMatrix(B, F)

# Warmup
bandpart(A)
fillpart(A)

# Test bandpart
allocs = @allocated bandpart(A)
@test allocs == 0

# Test fillpart
allocs = @allocated fillpart(A)
@test allocs == 0
@test isempty(check_allocs(bandpart, (typeof(A),)))
@test isempty(check_allocs(fillpart, (typeof(A),)))
end
end
Loading