@@ -171,11 +171,11 @@ b = [2.2, 3.3]; ∂f_∂b = zero(b)
171171c = 55; d = 9
172172
173173f(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
181181here, `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′... )
327334end
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′... )
345359end
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... )
637651end
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)
670706end
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)
732768end
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