Skip to content

Commit 9708efd

Browse files
wsmosesvchuravy
andauthored
Fastgen3 (#537)
Co-authored-by: Valentin Churavy <v.churavy@gmail.com>
1 parent a556f2e commit 9708efd

6 files changed

Lines changed: 879 additions & 571 deletions

File tree

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Enzyme"
22
uuid = "7da242da-08ed-463a-9acd-ee780be4f1d9"
33
authors = ["William Moses <wmoses@mit.edu>", "Valentin Churavy <vchuravy@mit.edu>"]
4-
version = "0.10.16"
4+
version = "0.11.0-dev"
55

66
[deps]
77
CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82"

src/Enzyme.jl

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,11 @@ b = [2.2, 3.3]; ∂f_∂b = zero(b)
171171
c = 55; d = 9
172172
173173
f(a, b, c, d) = a * √(b[1]^2 + b[2]^2) + c^2 * d^2
174-
∂f_∂a, ∂f_∂d = autodiff(Reverse, f, Active, Active(a), Duplicated(b, ∂f_∂b), c, Active(d))
174+
∂f_∂a, _, _, ∂f_∂d = autodiff(Reverse, f, Active, Active(a), Duplicated(b, ∂f_∂b), c, Active(d))[1]
175175
176176
# output
177177
178-
(3.966106403010388, 54450.0)
178+
(3.966106403010388, nothing, nothing, 54450.0)
179179
```
180180
181181
here, `autodiff` returns a tuple
@@ -319,9 +319,16 @@ f(x) = x*x
319319
if A <: Active
320320
throw(ErrorException("Active Returns not allowed in forward mode"))
321321
end
322-
323322
ReturnPrimal = Val(A <: Duplicated || A <: BatchDuplicated)
324-
thunk = Enzyme.Compiler.thunk(f, #=df=#nothing, A, tt′, #=Mode=# Val(API.DEM_ForwardMode), Val(width),
323+
RT = if A <: Duplicated && width != 1
324+
BatchDuplicated{eltype(A), width}
325+
elseif A <: DuplicatedNoNeed && width != 1
326+
BatchDuplicatedNoNeed{eltype(A), width}
327+
else
328+
A
329+
end
330+
331+
thunk = Enzyme.Compiler.thunk(f, #=df=#nothing, RT, tt′, #=Mode=# Val(API.DEM_ForwardMode), Val(width),
325332
#=ModifiedBetween=#Val(false), ReturnPrimal)
326333
thunk(args′...)
327334
end
@@ -340,7 +347,14 @@ end
340347
throw(ErrorException("Active Returns not allowed in forward mode"))
341348
end
342349
ReturnPrimal = Val(A <: Duplicated || A <: BatchDuplicated)
343-
thunk = Enzyme.Compiler.thunk(#=f=#dupf.val, #=df=#dupf.dval, A, tt′, #=Mode=# Val(API.DEM_ForwardMode), Val(width), #=ModifiedBetween=#Val(false), ReturnPrimal)
350+
RT = if A <: Duplicated && width != 1
351+
BatchDuplicated{eltype(A), width}
352+
elseif A <: DuplicatedNoNeed && width != 1
353+
BatchDuplicatedNoNeed{eltype(A), width}
354+
else
355+
A
356+
end
357+
thunk = Enzyme.Compiler.thunk(#=f=#dupf.val, #=df=#dupf.dval, RT, tt′, #=Mode=# Val(API.DEM_ForwardMode), Val(width), #=ModifiedBetween=#Val(false), ReturnPrimal)
344358
thunk(args′...)
345359
end
346360

@@ -626,7 +640,7 @@ grad = gradient(Forward, f, [2.0, 3.0], Val(2))
626640
(3.0, 2.0)
627641
```
628642
"""
629-
@inline function gradient(::ForwardMode, f, x, ::Val{chunk}; shadow=chunkedonehot(x, Val(chunk))) where chunk
643+
@inline function gradient(::ForwardMode, f::F, x::X, ::Val{chunk}; shadow=chunkedonehot(x, Val(chunk))) where {F, X, chunk}
630644
if chunk == 0
631645
throw(ErrorException("Cannot differentiate with a batch size of 0"))
632646
end
@@ -636,7 +650,7 @@ grad = gradient(Forward, f, [2.0, 3.0], Val(2))
636650
tupleconcat(tmp...)
637651
end
638652

639-
@inline function gradient(::ForwardMode, f, x, ::Val{1}; shadow=onehot(x))
653+
@inline function gradient(::ForwardMode, f::F, x::X, ::Val{1}; shadow=onehot(x)) where {F,X}
640654
ntuple(length(shadow)) do i
641655
autodiff(Forward, f, DuplicatedNoNeed, Duplicated(x, shadow[i]))[1]
642656
end
@@ -664,8 +678,30 @@ grad = jacobian(Forward, f, [2.0, 3.0])
664678
0.0 1.0
665679
```
666680
"""
667-
@inline function jacobian(::ForwardMode, args...; kwargs...)
668-
cols = gradient(Forward, args...; kwargs...)
681+
@inline function jacobian(::ForwardMode, f, x; shadow=onehot(x))
682+
cols = if length(x) == 0
683+
return ()
684+
else
685+
values(only(autodiff(Forward, f, BatchDuplicatedNoNeed, BatchDuplicated(x, shadow))))
686+
end
687+
reduce(hcat, cols)
688+
end
689+
690+
@inline function jacobian(::ForwardMode, f::F, x::X, ::Val{chunk}; shadow=chunkedonehot(x, Val(chunk))) where {F, X, chunk}
691+
if chunk == 0
692+
throw(ErrorException("Cannot differentiate with a batch size of 0"))
693+
end
694+
tmp = ntuple(length(shadow)) do i
695+
values(autodiff(Forward, f, BatchDuplicatedNoNeed, BatchDuplicated(x, shadow[i]))[1])
696+
end
697+
cols = tupleconcat(tmp...)
698+
reduce(hcat, cols)
699+
end
700+
701+
@inline function jacobian(::ForwardMode, f::F, x::X, ::Val{1}; shadow=onehot(x)) where {F,X}
702+
cols = ntuple(length(shadow)) do i
703+
autodiff(Forward, f, DuplicatedNoNeed, Duplicated(x, shadow[i]))[1]
704+
end
669705
reduce(hcat, cols)
670706
end
671707

@@ -690,7 +726,7 @@ grad = jacobian(Reverse, f, [2.0, 3.0], Val(2))
690726
0.0 1.0
691727
```
692728
"""
693-
@inline function jacobian(::ReverseMode, f, x, n_outs::Val{n_out_val}, ::Val{chunk}) where {chunk, n_out_val}
729+
@inline function jacobian(::ReverseMode, f::F, x::X, n_outs::Val{n_out_val}, ::Val{chunk}) where {F, X, chunk, n_out_val}
694730
num = ((n_out_val + chunk - 1) ÷ chunk)
695731

696732
if chunk == 0
@@ -731,7 +767,7 @@ grad = jacobian(Reverse, f, [2.0, 3.0], Val(2))
731767
mapreduce(LinearAlgebra.adjoint, vcat, rows)
732768
end
733769

734-
@inline function jacobian(::ReverseMode, f, x, n_outs::Val{n_out_val}, ::Val{1} = Val(1)) where {n_out_val}
770+
@inline function jacobian(::ReverseMode, f::F, x::X, n_outs::Val{n_out_val}, ::Val{1} = Val(1)) where {F, X, n_out_val}
735771
tt′ = Tuple{Duplicated{Core.Typeof(x)}}
736772
tt = Tuple{Core.Typeof(x)}
737773
rt = Core.Compiler.return_type(f, tt)

0 commit comments

Comments
 (0)