Skip to content

Commit 41bbb2c

Browse files
committed
Improve ladj summation dispatch
1 parent 161a46a commit 41bbb2c

2 files changed

Lines changed: 23 additions & 26 deletions

File tree

src/with_ladj.jl

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -109,48 +109,41 @@ function with_logabsdet_jacobian(f::Base.ComposedFunction, x)
109109
end
110110

111111

112-
_with_ladj_on_mapped(y_with_ladj::NoLogAbsDetJacobian) = y_with_ladj
113-
114-
_with_ladj_on_mapped(y_with_ladj::Tuple{Any,Real}) = y_with_ladj
115-
116-
_with_ladj_on_mapped(::AbstractArray{<:NoLogAbsDetJacobian{F,T}}) where {F,T} = NoLogAbsDetJacobian{F,T}()
117-
118112
_get_all_first(x) = map(first, x)
119113
_get_second(x) = x[2]
120114
# Use _get_second instead of last, using last causes horrible performance in Zygote here:
121115
_sum_over_second(x) = sum(_get_second, x)
122116

123-
function _with_ladj_on_mapped(y_with_ladj)
124-
y = _get_all_first(y_with_ladj)
125-
ladj = _sum_over_second(y_with_ladj)
126-
(y, ladj)
127-
end
128-
129-
_combine_y_ladj(l::NoLogAbsDetJacobian, @nospecialize(r::NoLogAbsDetJacobian)) = l
130-
_combine_y_ladj(l::NoLogAbsDetJacobian, @nospecialize(r::Tuple{Any,Real})) = l
131-
_combine_y_ladj(@nospecialize(l::Tuple{Any,Real}), r::NoLogAbsDetJacobian) = r
132-
_combine_y_ladj(l::Tuple{Any,Real}, r::Tuple{Any,Real}) = ((l[1]..., r[1]), l[2] + r[2])
117+
_combine_y_ladj(l, r) = ((l[1]..., r[1]), l[2] + r[2])
133118

134-
function _with_ladj_on_mapped(y_with_ladj::Tuple{NoLogAbsDetJacobian, Vararg{Union{NoLogAbsDetJacobian, Tuple{Any,Real}}}})
135-
return first(y_with_ladj)
136-
end
119+
_with_ladj_on_mapped(y_with_ladj::Tuple{Any,Any}, ::NoLogAbsDetJacobian) = y_with_ladj
137120

138-
function _with_ladj_on_mapped(y_with_ladj::Tuple{Tuple{Any,Real}, Vararg{Union{NoLogAbsDetJacobian, Tuple{Any,Real}}}})
121+
function _with_ladj_on_mapped(y_with_ladj::Tuple{Tuple{Any,Any}, Vararg{Tuple{Any,Any}}}, ::NoLogAbsDetJacobian)
139122
a, bs = first(y_with_ladj), Base.tail(y_with_ladj)
140123
return foldl(_combine_y_ladj, bs, init = ((a[1],), a[2]))
141124
end
142125

126+
_with_ladj_on_mapped(y_with_ladj::Tuple{Vararg{Union{Tuple{Any,Any},NoLogAbsDetJacobian}}}, noladj::NoLogAbsDetJacobian) = noladj
127+
128+
function _with_ladj_on_mapped(y_with_ladj::AbstractArray{<:Tuple{Any,Any}}, ::NoLogAbsDetJacobian)
129+
y = _get_all_first(y_with_ladj)
130+
ladj = _sum_over_second(y_with_ladj)
131+
(y, ladj)
132+
end
133+
134+
_with_ladj_on_mapped(::Any, noladj::NoLogAbsDetJacobian) = noladj
135+
143136
function with_logabsdet_jacobian(mapped_f::Base.Broadcast.BroadcastFunction, X)
144137
f = mapped_f.f
145138
y_with_ladj = broadcast(Base.Fix1(with_logabsdet_jacobian, f), X)
146-
_with_ladj_on_mapped(y_with_ladj)
139+
_with_ladj_on_mapped(y_with_ladj, NoLogAbsDetJacobian(mapped_f, X))
147140
end
148141

149142
function with_logabsdet_jacobian(mapped_f::Base.Fix1{<:Union{typeof(map),typeof(broadcast)}}, X)
150143
map_or_bc = mapped_f.f
151144
f = mapped_f.x
152145
y_with_ladj = map_or_bc(Base.Fix1(with_logabsdet_jacobian, f), X)
153-
_with_ladj_on_mapped(y_with_ladj)
146+
_with_ladj_on_mapped(y_with_ladj, NoLogAbsDetJacobian(mapped_f, X))
154147
end
155148

156149

test/test_with_ladj.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ include("getjacobian.jl")
2626
@test with_logabsdet_jacobian(sin log, 4.9) === NoLogAbsDetJacobian{typeof(sin ∘ log), Float64}()
2727
@test with_logabsdet_jacobian(log sin, 4.9) === NoLogAbsDetJacobian{typeof(log ∘ sin), Float64}()
2828

29-
@test with_logabsdet_jacobian(Base.Fix1(broadcast, sin), 4.9) === NoLogAbsDetJacobian{typeof(sin), Float64}()
29+
@test with_logabsdet_jacobian(Base.Fix1(broadcast, sin), 4.9) === NoLogAbsDetJacobian(Base.Fix1(broadcast, sin), 4.9)
3030

3131
function ChangesOfVariables.with_logabsdet_jacobian(::typeof(foo), x)
3232
y = foo(x)
@@ -58,15 +58,19 @@ include("getjacobian.jl")
5858
@testset "with_logabsdet_jacobian on mapped and broadcasted without ladj" begin
5959
for f in (_bc_func(sin), Base.Fix1(map, sin), Base.Fix1(broadcast, sin))
6060
for arg in (x, (x,), (x, x), X)
61-
@test with_logabsdet_jacobian(f, arg) isa NoLogAbsDetJacobian{typeof(sin)}
61+
@test with_logabsdet_jacobian(f, arg) === NoLogAbsDetJacobian(f, arg)
6262
end
6363
end
6464
end
6565

6666
@testset "with_logabsdet_jacobian on mapped and broadcasted with mixed ladj" begin
6767
@test with_logabsdet_jacobian(_bc_func(bar), (1.0, 2.0)) == ((1.0, 2.0), 0.0)
68-
@test with_logabsdet_jacobian(_bc_func(bar), (1.0, 2)) isa NoLogAbsDetJacobian
69-
@test with_logabsdet_jacobian(Base.Fix1(map, bar), (1, 2.0)) isa NoLogAbsDetJacobian
68+
@test with_logabsdet_jacobian(_bc_func(bar), [1.0, 2.0]) == ([1.0, 2.0], 0.0)
69+
@test with_logabsdet_jacobian(_bc_func(bar), (1.0, 2)) === NoLogAbsDetJacobian(_bc_func(bar), (1.0, 2))
70+
@test with_logabsdet_jacobian(Base.Fix1(map, bar), (1, 2.0)) === NoLogAbsDetJacobian(Base.Fix1(map, bar), (1, 2.0))
71+
@test with_logabsdet_jacobian(_bc_func(bar), Real[1.0, 2]) === NoLogAbsDetJacobian(_bc_func(bar), Real[1.0, 2])
72+
@test with_logabsdet_jacobian(Base.Fix1(map, bar), Real[1, 2.0]) === NoLogAbsDetJacobian(Base.Fix1(map, bar), Real[1, 2.0])
73+
@test with_logabsdet_jacobian(Base.Fix1(broadcast, bar), Real[1, 2]) === NoLogAbsDetJacobian(Base.Fix1(broadcast, bar), Real[1, 2])
7074
end
7175

7276
@testset "with_logabsdet_jacobian on identity, adjoint and transpose" begin

0 commit comments

Comments
 (0)