From d637b710707ea0484758ca0926ee33cf90ee79a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Thu, 11 Jun 2026 15:27:23 -0400 Subject: [PATCH 01/11] add `maketag` function --- ext/ForwardDiffStaticArraysExt.jl | 14 +++++++------- src/config.jl | 15 +++++++++------ src/derivative.jl | 4 ++-- test/JacobianTest.jl | 2 +- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/ext/ForwardDiffStaticArraysExt.jl b/ext/ForwardDiffStaticArraysExt.jl index bf0ef99a..a8678f44 100644 --- a/ext/ForwardDiffStaticArraysExt.jl +++ b/ext/ForwardDiffStaticArraysExt.jl @@ -3,7 +3,7 @@ module ForwardDiffStaticArraysExt using ForwardDiff, StaticArrays using ForwardDiff.LinearAlgebra using ForwardDiff.DiffResults -using ForwardDiff: Dual, partials, npartials, Partials, GradientConfig, JacobianConfig, HessianConfig, Tag, Chunk, +using ForwardDiff: Dual, partials, npartials, Partials, GradientConfig, JacobianConfig, HessianConfig, Tag, Chunk, maketag gradient, hessian, jacobian, gradient!, hessian!, jacobian!, extract_gradient!, extract_jacobian!, extract_value!, vector_mode_gradient, vector_mode_gradient!, @@ -51,12 +51,12 @@ ForwardDiff._lyap_div!!(A::StaticArrays.MMatrix, λ::AbstractVector) = ForwardDi end @inline function ForwardDiff.vector_mode_gradient(f::F, x::StaticArray) where {F} - T = typeof(Tag(f, eltype(x))) + T = typeof(maketag(f,eltype(x))) return extract_gradient(T, f(dualize(T, x)), x) end @inline function ForwardDiff.vector_mode_gradient!(result, f::F, x::StaticArray) where {F} - T = typeof(Tag(f, eltype(x))) + T = typeof(maketag(f,eltype(x))) return extract_gradient!(T, result, f(dualize(T, x))) end @@ -81,7 +81,7 @@ end end @inline function ForwardDiff.vector_mode_jacobian(f::F, x::StaticArray) where {F} - T = typeof(Tag(f, eltype(x))) + T = typeof(maketag(f,eltype(x))) return extract_jacobian(T, f(dualize(T, x)), x) end @@ -91,7 +91,7 @@ function extract_jacobian(::Type{T}, ydual::AbstractArray, x::StaticArray) where end @inline function ForwardDiff.vector_mode_jacobian!(result, f::F, x::StaticArray) where {F} - T = typeof(Tag(f, eltype(x))) + T = typeof(maketag(f,eltype(x))) ydual = f(dualize(T, x)) result = extract_jacobian!(T, result, ydual, length(x)) result = extract_value!(T, result, ydual) @@ -99,7 +99,7 @@ end end @inline function ForwardDiff.vector_mode_jacobian!(result::ImmutableDiffResult, f::F, x::StaticArray) where {F} - T = typeof(Tag(f, eltype(x))) + T = typeof(maketag(f,eltype(x))) ydual = f(dualize(T, x)) result = DiffResults.jacobian!(result, extract_jacobian(T, ydual, x)) result = DiffResults.value!(Base.Fix1(value, T), result, ydual) @@ -119,7 +119,7 @@ ForwardDiff.hessian!(result::ImmutableDiffResult, f::F, x::StaticArray, cfg::Hes ForwardDiff.hessian!(result::ImmutableDiffResult, f::F, x::StaticArray, cfg::HessianConfig, ::Val) where {F} = hessian!(result, f, x) function ForwardDiff.hessian!(result::ImmutableDiffResult, f::F, x::StaticArray) where {F} - T = typeof(Tag(f, eltype(x))) + T = typeof(maketag(f,eltype(x))) d1 = dualize(T, x) d2 = dualize(T, d1) fd2 = f(d2) diff --git a/src/config.jl b/src/config.jl index 3c6c97e3..00d82a99 100644 --- a/src/config.jl +++ b/src/config.jl @@ -42,6 +42,9 @@ checktag(::Type{Tag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT<:Tuple,VT,F,V} # custom tag: you're on your own. checktag(z, f, x) = true +#Tag maker function +maketag(f::F,::Type{V}) where {F,V} = maketag(f, V) +maketag(::Nothing,::Type{V}) where {V} = nothing ################## # AbstractConfig # @@ -82,7 +85,7 @@ This constructor does not store/modify `y` or `x`. function DerivativeConfig(f::F, y::AbstractArray{Y}, x::X, - tag::T = Tag(f, X)) where {F,X<:Real,Y<:Real,T} + tag::T = maketag(f, X)) where {F,X<:Real,Y<:Real,T} duals = similar(y, Dual{T,Y,1}) return DerivativeConfig{T,typeof(duals)}(duals) end @@ -117,7 +120,7 @@ This constructor does not store/modify `x`. function GradientConfig(f::F, x::AbstractArray{V}, ::Chunk{N} = Chunk(x), - ::T = Tag(f, V)) where {F,V,N,T} + ::T = maketag(f, V)) where {F,V,N,T} seeds = construct_seeds(Partials{N,V}) duals = similar(x, Dual{T,V,N}) return GradientConfig{T,V,N,typeof(duals)}(seeds, duals) @@ -154,7 +157,7 @@ This constructor does not store/modify `x`. function JacobianConfig(f::F, x::AbstractArray{V}, ::Chunk{N} = Chunk(x), - ::T = Tag(f, V)) where {F,V,N,T} + ::T = maketag(f, V)) where {F,V,N,T} seeds = construct_seeds(Partials{N,V}) duals = similar(x, Dual{T,V,N}) return JacobianConfig{T,V,N,typeof(duals)}(seeds, duals) @@ -180,7 +183,7 @@ function JacobianConfig(f::F, y::AbstractArray{Y}, x::AbstractArray{X}, ::Chunk{N} = Chunk(x), - ::T = Tag(f, X)) where {F,Y,X,N,T} + ::T = maketag(f, X)) where {F,Y,X,N,T} seeds = construct_seeds(Partials{N,X}) yduals = similar(y, Dual{T,Y,N}) xduals = similar(x, Dual{T,X,N}) @@ -221,7 +224,7 @@ This constructor does not store/modify `x`. function HessianConfig(f::F, x::AbstractArray{V}, chunk::Chunk = Chunk(x), - tag = Tag(f, V)) where {F,V} + tag = maketag(f, V)) where {F,V} jacobian_config = JacobianConfig(f, x, chunk, tag) gradient_config = GradientConfig(f, jacobian_config.duals, chunk, tag) return HessianConfig(jacobian_config, gradient_config) @@ -246,7 +249,7 @@ function HessianConfig(f::F, result::DiffResult, x::AbstractArray{V}, chunk::Chunk = Chunk(x), - tag = Tag(f, V)) where {F,V} + tag = maketag(f, V)) where {F,V} jacobian_config = JacobianConfig((f,gradient), DiffResults.gradient(result), x, chunk, tag) gradient_config = GradientConfig(f, jacobian_config.duals[2], chunk, tag) return HessianConfig(jacobian_config, gradient_config) diff --git a/src/derivative.jl b/src/derivative.jl index b39e2a48..3b2ba64d 100644 --- a/src/derivative.jl +++ b/src/derivative.jl @@ -10,7 +10,7 @@ Return `df/dx` evaluated at `x`, assuming `f` is called as `f(x)`. This method assumes that `isa(f(x), Union{Real,AbstractArray})`. """ @inline function derivative(f::F, x::R) where {F,R<:Real} - T = typeof(Tag(f, R)) + T = typeof(maketag(f, R)) return extract_derivative(T, f(Dual{T}(x, one(x)))) end @@ -44,7 +44,7 @@ This method assumes that `isa(f(x), Union{Real,AbstractArray})`. @inline function derivative!(result::Union{AbstractArray,DiffResult}, f::F, x::R) where {F,R<:Real} result isa DiffResult || require_one_based_indexing(result) - T = typeof(Tag(f, R)) + T = typeof(maketag(f, R)) ydual = f(Dual{T}(x, one(x))) result = extract_value!(T, result, ydual) result = extract_derivative!(T, result, ydual) diff --git a/test/JacobianTest.jl b/test/JacobianTest.jl index 9cc5024c..454f19c7 100644 --- a/test/JacobianTest.jl +++ b/test/JacobianTest.jl @@ -110,7 +110,7 @@ for f in DiffTests.ARRAY_TO_ARRAY_FUNCS @test isapprox(j, Calculus.jacobian(x -> vec(f(x)), X, :forward), atol=1.3FINITEDIFF_ERROR) @testset "$f with chunk size = $c and tag = $(repr(tag))" for c in CHUNK_SIZES, tag in (nothing, Tag) if tag == Tag - tag = Tag(f, eltype(X)) + tag = maketag(f, eltype(X)) end cfg = JacobianConfig(f, X, ForwardDiff.Chunk{c}(), tag) From 361d701e4be68b422e054c83e1404570ccf14f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:00:11 -0400 Subject: [PATCH 02/11] define AbstractTag and api --- ext/ForwardDiffStaticArraysExt.jl | 12 +++++----- src/config.jl | 38 +++++++++++++++++++++++++------ src/derivative.jl | 4 ++-- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/ext/ForwardDiffStaticArraysExt.jl b/ext/ForwardDiffStaticArraysExt.jl index a8678f44..a566adf5 100644 --- a/ext/ForwardDiffStaticArraysExt.jl +++ b/ext/ForwardDiffStaticArraysExt.jl @@ -51,12 +51,12 @@ ForwardDiff._lyap_div!!(A::StaticArrays.MMatrix, λ::AbstractVector) = ForwardDi end @inline function ForwardDiff.vector_mode_gradient(f::F, x::StaticArray) where {F} - T = typeof(maketag(f,eltype(x))) + T = maketagtype(f,eltype(x)) return extract_gradient(T, f(dualize(T, x)), x) end @inline function ForwardDiff.vector_mode_gradient!(result, f::F, x::StaticArray) where {F} - T = typeof(maketag(f,eltype(x))) + T = maketagtype(f,eltype(x)) return extract_gradient!(T, result, f(dualize(T, x))) end @@ -81,7 +81,7 @@ end end @inline function ForwardDiff.vector_mode_jacobian(f::F, x::StaticArray) where {F} - T = typeof(maketag(f,eltype(x))) + T = maketagtype(f,eltype(x)) return extract_jacobian(T, f(dualize(T, x)), x) end @@ -91,7 +91,7 @@ function extract_jacobian(::Type{T}, ydual::AbstractArray, x::StaticArray) where end @inline function ForwardDiff.vector_mode_jacobian!(result, f::F, x::StaticArray) where {F} - T = typeof(maketag(f,eltype(x))) + T = maketagtype(f,eltype(x)) ydual = f(dualize(T, x)) result = extract_jacobian!(T, result, ydual, length(x)) result = extract_value!(T, result, ydual) @@ -99,7 +99,7 @@ end end @inline function ForwardDiff.vector_mode_jacobian!(result::ImmutableDiffResult, f::F, x::StaticArray) where {F} - T = typeof(maketag(f,eltype(x))) + T = maketagtype(f,eltype(x)) ydual = f(dualize(T, x)) result = DiffResults.jacobian!(result, extract_jacobian(T, ydual, x)) result = DiffResults.value!(Base.Fix1(value, T), result, ydual) @@ -119,7 +119,7 @@ ForwardDiff.hessian!(result::ImmutableDiffResult, f::F, x::StaticArray, cfg::Hes ForwardDiff.hessian!(result::ImmutableDiffResult, f::F, x::StaticArray, cfg::HessianConfig, ::Val) where {F} = hessian!(result, f, x) function ForwardDiff.hessian!(result::ImmutableDiffResult, f::F, x::StaticArray) where {F} - T = typeof(maketag(f,eltype(x))) + T = maketagtype(f,eltype(x)) d1 = dualize(T, x) d2 = dualize(T, d1) fd2 = f(d2) diff --git a/src/config.jl b/src/config.jl index 00d82a99..07d362b1 100644 --- a/src/config.jl +++ b/src/config.jl @@ -1,8 +1,23 @@ +#= +###### +# AbstractTag interface + +Required definitions: +- ≺ (between two AbstractTags of the same type) +- maketagtype(f,::Type{V}) where {V <: Real} + +Optional definitions: +- ≺ (between two AbstractTags of the of different type) +- maketag(f,::Type{V}) where {V <: Real} (default: defined in terms of maketagtype) +- checktag(tag::MyTagType,f,x) +###### +=# +abstract type AbstractTag{F,V} end + ####### # Tag # ####### - -struct Tag{F,V} +struct Tag{F,V} <: AbstractTag{F,V} end end const TAGCOUNT = Threads.Atomic{UInt}(0) @@ -20,11 +35,15 @@ end Tag(::Nothing, ::Type{V}) where {V} = nothing - @inline function ≺(::Type{Tag{F1,V1}}, ::Type{Tag{F2,V2}}) where {F1,V1,F2,V2} tagcount(Tag{F1,V1}) < tagcount(Tag{F2,V2}) end +@inline maketagtype(f::F,::Type{V}) = Tag{F,V} +@inline maketagtype(f::Nothing,::Type{V}) = Nothing + +@inline maketag(f::F,::Type{V}) = maketagtype(f,V)() + struct InvalidTagException{E,O} <: Exception end @@ -38,13 +57,18 @@ checktag(::Type{Tag{F,V}}, f::F, x::AbstractArray{V}) where {F,V} = true # no easy way to check Jacobian tag used with Hessians as multiple functions may be used checktag(::Type{Tag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT<:Tuple,VT,F,V} = true +checktag(::Type{AbstractTag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT<:Tuple,VT,F,V} = true + +#AbstractTag support +checktag(T::Type{AbstractTag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT,VT,F,V} = + T2 = maketagtype(f,V) #maketag(f::F,type{V})::AbstractTag{F2,V2} is not equivalent to Tag{F,V} + T2 !== T && throw(InvalidTagException{T,T2}()) + return true +end -# custom tag: you're on your own. +# custom tag not in the tag API: you're on your own. checktag(z, f, x) = true -#Tag maker function -maketag(f::F,::Type{V}) where {F,V} = maketag(f, V) -maketag(::Nothing,::Type{V}) where {V} = nothing ################## # AbstractConfig # diff --git a/src/derivative.jl b/src/derivative.jl index 3b2ba64d..2ec0b8fc 100644 --- a/src/derivative.jl +++ b/src/derivative.jl @@ -10,7 +10,7 @@ Return `df/dx` evaluated at `x`, assuming `f` is called as `f(x)`. This method assumes that `isa(f(x), Union{Real,AbstractArray})`. """ @inline function derivative(f::F, x::R) where {F,R<:Real} - T = typeof(maketag(f, R)) + T = maketagtype(f,R) return extract_derivative(T, f(Dual{T}(x, one(x)))) end @@ -44,7 +44,7 @@ This method assumes that `isa(f(x), Union{Real,AbstractArray})`. @inline function derivative!(result::Union{AbstractArray,DiffResult}, f::F, x::R) where {F,R<:Real} result isa DiffResult || require_one_based_indexing(result) - T = typeof(maketag(f, R)) + T = maketagtype(f,R) ydual = f(Dual{T}(x, one(x))) result = extract_value!(T, result, ydual) result = extract_derivative!(T, result, ydual) From 0a97948f8fc4119503cdf97653c4dc256c8d2148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:33:39 -0400 Subject: [PATCH 03/11] typo --- src/config.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/config.jl b/src/config.jl index 07d362b1..21ccf26d 100644 --- a/src/config.jl +++ b/src/config.jl @@ -18,7 +18,6 @@ abstract type AbstractTag{F,V} end # Tag # ####### struct Tag{F,V} <: AbstractTag{F,V} end -end const TAGCOUNT = Threads.Atomic{UInt}(0) From 413713438bad4ed113baaccffe9a426e5ad3d3c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:35:32 -0400 Subject: [PATCH 04/11] missing type declarations --- src/config.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/config.jl b/src/config.jl index 21ccf26d..9c9e6eee 100644 --- a/src/config.jl +++ b/src/config.jl @@ -38,10 +38,10 @@ Tag(::Nothing, ::Type{V}) where {V} = nothing tagcount(Tag{F1,V1}) < tagcount(Tag{F2,V2}) end -@inline maketagtype(f::F,::Type{V}) = Tag{F,V} -@inline maketagtype(f::Nothing,::Type{V}) = Nothing +@inline maketagtype(f::F,::Type{V}) where {F,V} = Tag{F,V} +@inline maketagtype(f::Nothing,::Type{V}) where {F,V} = Nothing -@inline maketag(f::F,::Type{V}) = maketagtype(f,V)() +@inline maketag(f::F,::Type{V}) where {F,V} = maketagtype(f,V)() struct InvalidTagException{E,O} <: Exception end From d2e115456c5dfa49f2269f0d0ee1070bd9e6aa8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:40:13 -0400 Subject: [PATCH 05/11] fix checktag def --- src/config.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config.jl b/src/config.jl index 9c9e6eee..0e67cd11 100644 --- a/src/config.jl +++ b/src/config.jl @@ -39,7 +39,7 @@ Tag(::Nothing, ::Type{V}) where {V} = nothing end @inline maketagtype(f::F,::Type{V}) where {F,V} = Tag{F,V} -@inline maketagtype(f::Nothing,::Type{V}) where {F,V} = Nothing +@inline maketagtype(f::Nothing,::Type{V}) where {V} = Nothing @inline maketag(f::F,::Type{V}) where {F,V} = maketagtype(f,V)() @@ -59,7 +59,7 @@ checktag(::Type{Tag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT<:Tuple,VT,F,V} checktag(::Type{AbstractTag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT<:Tuple,VT,F,V} = true #AbstractTag support -checktag(T::Type{AbstractTag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT,VT,F,V} = +function checktag(T::Type{AbstractTag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT,VT,F,V} T2 = maketagtype(f,V) #maketag(f::F,type{V})::AbstractTag{F2,V2} is not equivalent to Tag{F,V} T2 !== T && throw(InvalidTagException{T,T2}()) return true From 157b5f0e3ddb025d876225a0a99a35c0a3906c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:43:31 -0400 Subject: [PATCH 06/11] fix ext --- ext/ForwardDiffStaticArraysExt.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ForwardDiffStaticArraysExt.jl b/ext/ForwardDiffStaticArraysExt.jl index a566adf5..7fe4bedc 100644 --- a/ext/ForwardDiffStaticArraysExt.jl +++ b/ext/ForwardDiffStaticArraysExt.jl @@ -3,7 +3,7 @@ module ForwardDiffStaticArraysExt using ForwardDiff, StaticArrays using ForwardDiff.LinearAlgebra using ForwardDiff.DiffResults -using ForwardDiff: Dual, partials, npartials, Partials, GradientConfig, JacobianConfig, HessianConfig, Tag, Chunk, maketag +using ForwardDiff: Dual, partials, npartials, Partials, GradientConfig, JacobianConfig, HessianConfig, Tag, Chunk, maketagtype, gradient, hessian, jacobian, gradient!, hessian!, jacobian!, extract_gradient!, extract_jacobian!, extract_value!, vector_mode_gradient, vector_mode_gradient!, From 4c38a9efd7a76ca2642166c68e96f5170d353bd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:54:05 -0400 Subject: [PATCH 07/11] move AbstractTag api to prelude --- src/config.jl | 20 +------------------- src/prelude.jl | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/config.jl b/src/config.jl index 0e67cd11..c5e1e6fd 100644 --- a/src/config.jl +++ b/src/config.jl @@ -1,19 +1,3 @@ -#= -###### -# AbstractTag interface - -Required definitions: -- ≺ (between two AbstractTags of the same type) -- maketagtype(f,::Type{V}) where {V <: Real} - -Optional definitions: -- ≺ (between two AbstractTags of the of different type) -- maketag(f,::Type{V}) where {V <: Real} (default: defined in terms of maketagtype) -- checktag(tag::MyTagType,f,x) -###### -=# -abstract type AbstractTag{F,V} end - ####### # Tag # ####### @@ -38,10 +22,8 @@ Tag(::Nothing, ::Type{V}) where {V} = nothing tagcount(Tag{F1,V1}) < tagcount(Tag{F2,V2}) end +#default implementation of maketagtyp @inline maketagtype(f::F,::Type{V}) where {F,V} = Tag{F,V} -@inline maketagtype(f::Nothing,::Type{V}) where {V} = Nothing - -@inline maketag(f::F,::Type{V}) where {F,V} = maketagtype(f,V)() struct InvalidTagException{E,O} <: Exception end diff --git a/src/prelude.jl b/src/prelude.jl index 9e037afa..0f804467 100644 --- a/src/prelude.jl +++ b/src/prelude.jl @@ -67,3 +67,22 @@ function qualified_cse!(expr) end return cse_expr end + +#= +###### +# AbstractTag interface + +Required definitions: +- ≺ (between two AbstractTags of the same type) +- maketagtype(f,::Type{V}) where {V <: Real} + +Optional definitions: +- ≺ (between two AbstractTags of the of different type) +- maketag(f,::Type{V}) where {V <: Real} (default: defined in terms of maketagtype) +- checktag(tag::MyTagType,f,x) +###### +=# +abstract type AbstractTag{F,V} end + +@inline maketagtype(f::Nothing,::Type{V}) where {V} = Nothing +@inline maketag(f::F,::Type{V}) where {F,V} = maketagtype(f,V)() From 9b3970224858f3862adbbd8c8692a9bfb3c194d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Thu, 11 Jun 2026 17:13:52 -0400 Subject: [PATCH 08/11] typo in jacobian test --- test/JacobianTest.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/JacobianTest.jl b/test/JacobianTest.jl index 454f19c7..9cc5024c 100644 --- a/test/JacobianTest.jl +++ b/test/JacobianTest.jl @@ -110,7 +110,7 @@ for f in DiffTests.ARRAY_TO_ARRAY_FUNCS @test isapprox(j, Calculus.jacobian(x -> vec(f(x)), X, :forward), atol=1.3FINITEDIFF_ERROR) @testset "$f with chunk size = $c and tag = $(repr(tag))" for c in CHUNK_SIZES, tag in (nothing, Tag) if tag == Tag - tag = maketag(f, eltype(X)) + tag = Tag(f, eltype(X)) end cfg = JacobianConfig(f, X, ForwardDiff.Chunk{c}(), tag) From 6f7abf69b00d08bc35809631f339e9cbb1103f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Thu, 11 Jun 2026 23:20:59 -0400 Subject: [PATCH 09/11] define maketag(f,V) = Tag(f,V) --- src/config.jl | 7 ++++++- src/prelude.jl | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/config.jl b/src/config.jl index c5e1e6fd..c3b24241 100644 --- a/src/config.jl +++ b/src/config.jl @@ -22,9 +22,14 @@ Tag(::Nothing, ::Type{V}) where {V} = nothing tagcount(Tag{F1,V1}) < tagcount(Tag{F2,V2}) end -#default implementation of maketagtyp +#default implementation of maketagtype @inline maketagtype(f::F,::Type{V}) where {F,V} = Tag{F,V} +#default implementation of maketag. +#Tag needs the two-arg form to register the tagcount +maketag(f::F,::Type{V}) where {F,V} = Tag(f,V) +#@inline maketag(f::F,::Type{V}) where {F,V} = maketagtype(f,V)() + struct InvalidTagException{E,O} <: Exception end diff --git a/src/prelude.jl b/src/prelude.jl index 0f804467..e0632975 100644 --- a/src/prelude.jl +++ b/src/prelude.jl @@ -85,4 +85,4 @@ Optional definitions: abstract type AbstractTag{F,V} end @inline maketagtype(f::Nothing,::Type{V}) where {V} = Nothing -@inline maketag(f::F,::Type{V}) where {F,V} = maketagtype(f,V)() +function maketag end From 792435c85017833c7bd8efa1361c43ea9ea0f524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Thu, 11 Jun 2026 23:39:47 -0400 Subject: [PATCH 10/11] maketagtype: instantiate tag when calling --- src/prelude.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/prelude.jl b/src/prelude.jl index e0632975..48aed5ee 100644 --- a/src/prelude.jl +++ b/src/prelude.jl @@ -74,15 +74,15 @@ end Required definitions: - ≺ (between two AbstractTags of the same type) -- maketagtype(f,::Type{V}) where {V <: Real} +- maketag(f,::Type{V}) where {V <: Real} Optional definitions: - ≺ (between two AbstractTags of the of different type) -- maketag(f,::Type{V}) where {V <: Real} (default: defined in terms of maketagtype) +- maketagtype(f,::Type{V}) where {V <: Real} (default: defined in terms of maketag) - checktag(tag::MyTagType,f,x) ###### =# abstract type AbstractTag{F,V} end -@inline maketagtype(f::Nothing,::Type{V}) where {V} = Nothing -function maketag end +maketag(::Nothing,::Type{V}) where {V} = nothing +@inline maketagtype(f::F,::Type{V}) where {F,V} = typeof(maketag(f,V)) From ecacc26f796cece5bbd72707380abda794ee6b38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Thu, 11 Jun 2026 23:49:50 -0400 Subject: [PATCH 11/11] remove maketagtype(f,::Type{V}) = Tag{f,V} --- src/config.jl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/config.jl b/src/config.jl index c3b24241..1fd2cbac 100644 --- a/src/config.jl +++ b/src/config.jl @@ -22,13 +22,8 @@ Tag(::Nothing, ::Type{V}) where {V} = nothing tagcount(Tag{F1,V1}) < tagcount(Tag{F2,V2}) end -#default implementation of maketagtype -@inline maketagtype(f::F,::Type{V}) where {F,V} = Tag{F,V} - #default implementation of maketag. -#Tag needs the two-arg form to register the tagcount maketag(f::F,::Type{V}) where {F,V} = Tag(f,V) -#@inline maketag(f::F,::Type{V}) where {F,V} = maketagtype(f,V)() struct InvalidTagException{E,O} <: Exception end