Skip to content

Commit

Permalink
Increase code coverage (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
adrhill authored Apr 29, 2024
1 parent bbcefc5 commit 8868ddb
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 15 deletions.
13 changes: 13 additions & 0 deletions src/adtypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ julia> ADTypes.jacobian_sparsity(diff, rand(4), TracerSparsityDetector())
⋅ 1 1 ⋅
⋅ ⋅ 1 1
```
```jldoctest
julia> using ADTypes, SparseConnectivityTracer
julia> f(x) = x[1] + x[2]*x[3] + 1/x[4];
julia> ADTypes.hessian_sparsity(f, rand(4), TracerSparsityDetector())
4×4 SparseArrays.SparseMatrixCSC{Bool, UInt64} with 3 stored entries:
⋅ ⋅ ⋅ ⋅
⋅ ⋅ 1 ⋅
⋅ 1 ⋅ ⋅
⋅ ⋅ ⋅ 1
```
"""
struct TracerSparsityDetector <: ADTypes.AbstractSparsityDetector end

Expand Down
28 changes: 19 additions & 9 deletions src/pattern.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,29 @@ Supports [`JacobianTracer`](@ref) and [`ConnectivityTracer`](@ref).
```jldoctest
julia> x = rand(3);
julia> f(x) = [x[1]^2, 2 * x[1] * x[2]^2, sin(x[3])];
julia> xt = trace_input(ConnectivityTracer, x)
julia> trace_input(ConnectivityTracer, x)
3-element Vector{ConnectivityTracer}:
ConnectivityTracer(1,)
ConnectivityTracer(2,)
ConnectivityTracer(3,)
julia> yt = f(xt)
3-element Vector{ConnectivityTracer}:
ConnectivityTracer(1,)
ConnectivityTracer(1, 2)
ConnectivityTracer(3,)
julia> trace_input(JacobianTracer, x)
3-element Vector{JacobianTracer}:
JacobianTracer(1,)
JacobianTracer(2,)
JacobianTracer(3,)
julia> trace_input(HessianTracer, x)
3-element Vector{HessianTracer}:
HessianTracer(
1 => (),
)
HessianTracer(
2 => (),
)
HessianTracer(
3 => (),
)
```
"""
trace_input(::Type{T}, x) where {T<:AbstractTracer} = trace_input(T, x, 1)
Expand Down Expand Up @@ -114,7 +124,7 @@ function pattern(f!, y, ::Type{T}, x) where {T<:AbstractTracer}
end

_pattern(xt::AbstractTracer, yt::Number) = _pattern([xt], [yt])
_pattern(xt::AbstractTracer, yt::AbstractArray{Number}) = _pattern([xt], yt)
_pattern(xt::AbstractTracer, yt::AbstractArray{<:Number}) = _pattern([xt], yt)
_pattern(xt::AbstractArray{<:AbstractTracer}, yt::Number) = _pattern(xt, [yt])
function _pattern(xt::AbstractArray{<:AbstractTracer}, yt::AbstractArray{<:Number})
return _pattern_to_sparsemat(xt, yt)
Expand Down
2 changes: 1 addition & 1 deletion src/tracers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ function Base.show(io::IO, t::HessianTracer)
Base.show_delim_array(io, collect(t.inputs[key]), "(", ',', ')', true)
println(io, ",")
end
return println(io, ")")
return print(io, ")")
end

const EMPTY_HESSIAN_TRACER = HessianTracer(HessianDict())
Expand Down
1 change: 1 addition & 0 deletions test/references/show/ConnectivityTracer.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ConnectivityTracer(1, 2, 3)
5 changes: 5 additions & 0 deletions test/references/show/HessianTracer.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
HessianTracer(
2 => (),
3 => (),
1 => (),
)
1 change: 1 addition & 0 deletions test/references/show/JacobianTracer.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
JacobianTracer(1, 2, 3)
121 changes: 116 additions & 5 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using SparseConnectivityTracer
using SparseConnectivityTracer: trace_input
using SparseConnectivityTracer: trace_input, empty

using Test
using ReferenceTests
Expand Down Expand Up @@ -74,6 +74,43 @@ DocMeta.setdocmeta!(
g(x) = [x[1] * x[2], ceil(x[1] * x[2]), x[1] * round(x[2])]
@test pattern(g, ConnectivityTracer, x) [1 1; 1 1; 1 1]
@test pattern(g, JacobianTracer, x) [1 1; 0 0; 1 0]

# Code coverage
@test pattern(x -> [sincos(x)...], ConnectivityTracer, 1) [1; 1]
@test pattern(x -> [sincos(x)...], JacobianTracer, 1) [1; 1]
@test pattern(typemax, ConnectivityTracer, 1) [0;;]
@test pattern(typemax, JacobianTracer, 1) [0;;]
@test pattern(x -> x^(2//3), ConnectivityTracer, 1) [1;;]
@test pattern(x -> x^(2//3), JacobianTracer, 1) [1;;]
@test pattern(x -> (2//3)^x, ConnectivityTracer, 1) [1;;]
@test pattern(x -> (2//3)^x, JacobianTracer, 1) [1;;]
@test pattern(x -> x^ℯ, ConnectivityTracer, 1) [1;;]
@test pattern(x -> x^ℯ, JacobianTracer, 1) [1;;]
@test pattern(x ->^x, ConnectivityTracer, 1) [1;;]
@test pattern(x ->^x, JacobianTracer, 1) [1;;]
@test pattern(x -> round(x, RoundNearestTiesUp), ConnectivityTracer, 1) [1;;]
@test pattern(x -> round(x, RoundNearestTiesUp), JacobianTracer, 1) [0;;]

@test rand(ConnectivityTracer) == empty(ConnectivityTracer)
@test rand(JacobianTracer) == empty(JacobianTracer)

t = tracer(ConnectivityTracer, 1, 2, 3)
@test ConnectivityTracer(t) == t
@test empty(t) == empty(ConnectivityTracer)
@test ConnectivityTracer(1) == empty(ConnectivityTracer)

t = tracer(JacobianTracer, 1, 2, 3)
@test JacobianTracer(t) == t
@test empty(t) == empty(JacobianTracer)
@test JacobianTracer(1) == empty(JacobianTracer)

# Base.show
@test_reference "references/show/ConnectivityTracer.txt" repr(
"text/plain", tracer(ConnectivityTracer, 1, 2, 3)
)
@test_reference "references/show/JacobianTracer.txt" repr(
"text/plain", tracer(JacobianTracer, 1, 2, 3)
)
end
@testset "Second order" begin
@test pattern(identity, HessianTracer, rand()) [0;;]
Expand All @@ -82,9 +119,78 @@ DocMeta.setdocmeta!(
@test pattern(x -> 1 * x, HessianTracer, rand()) [0;;]
@test pattern(x -> x * 1, HessianTracer, rand()) [0;;]

x = rand(5)
f(x) = x[1] + x[2] * x[3] + 1 / x[4] + 1 * x[5]
# Code coverage
@test pattern(typemax, HessianTracer, 1) [0;;]
@test pattern(x -> x^(2im), HessianTracer, 1) [1;;]
@test pattern(x -> (2im)^x, HessianTracer, 1) [1;;]
@test pattern(x -> x^(2//3), HessianTracer, 1) [1;;]
@test pattern(x -> (2//3)^x, HessianTracer, 1) [1;;]
@test pattern(x -> x^ℯ, HessianTracer, 1) [1;;]
@test pattern(x ->^x, HessianTracer, 1) [1;;]
@test pattern(x -> round(x, RoundNearestTiesUp), HessianTracer, 1) [0;;]

@test rand(HessianTracer) == empty(HessianTracer)

t = tracer(HessianTracer, 1, 2, 3)
@test HessianTracer(t) == t
@test empty(t) == empty(HessianTracer)
@test HessianTracer(1) == empty(HessianTracer)

x = rand(4)

f(x) = x[1] / x[2] + x[3] / 1 + 1 / x[4]
H = pattern(f, HessianTracer, x)
@test H [
0 1 0 0
1 1 0 0
0 0 0 0
0 0 0 1
]

f(x) = x[1] * x[2] + x[3] * 1 + 1 * x[4]
H = pattern(f, HessianTracer, x)
@test H [
0 1 0 0
1 0 0 0
0 0 0 0
0 0 0 0
]

f(x) = (x[1] - x[2]) + (x[3] - 1) + (1 - x[4])
H = pattern(f, HessianTracer, x)
@test H [
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
]

f(x) = copysign(x[1] * x[2], x[3] * x[4])
H = pattern(f, HessianTracer, x)
@test H [
0 1 0 0
1 0 0 0
0 0 0 0
0 0 0 0
]

f(x) = div(x[1] * x[2], x[3] * x[4])
H = pattern(f, HessianTracer, x)
@test H [
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
]

x = rand()
f(x) = sum(sincosd(x))
H = pattern(f, HessianTracer, x)
@test H [1;;]

x = rand(5)
foo(x) = x[1] + x[2] * x[3] + 1 / x[4] + 1 * x[5]
H = pattern(foo, HessianTracer, x)
@test H [
0 0 0 0 0
0 0 1 0 0
Expand All @@ -93,15 +199,20 @@ DocMeta.setdocmeta!(
0 0 0 0 0
]

g(x) = f(x) + x[2]^x[5]
H = pattern(g, HessianTracer, x)
bar(x) = foo(x) + x[2]^x[5]
H = pattern(bar, HessianTracer, x)
@test H [
0 0 0 0 0
0 1 1 0 1
0 1 0 0 0
0 0 0 1 0
0 1 0 0 1
]

# Base.show
@test_reference "references/show/HessianTracer.txt" repr(
"text/plain", tracer(HessianTracer, 1, 2, 3)
)
end
@testset "Real-world tests" begin
@testset "NNlib" begin
Expand Down

0 comments on commit 8868ddb

Please sign in to comment.