20
20
21
21
Tag (:: Nothing , :: Type{V} ) where {V} = nothing
22
22
23
-
24
23
@inline function ≺ (:: Type{Tag{F1,V1}} , :: Type{Tag{F2,V2}} ) where {F1,V1,F2,V2}
25
24
tagcount (Tag{F1,V1}) < tagcount (Tag{F2,V2})
26
25
end
27
26
27
+ # SmallTag is similar to a Tag, but carries just a small UInt64 hash, instead
28
+ # of the full type, which makes stacktraces / types easier to read while still
29
+ # providing good resilience to perturbation confusion.
30
+ struct SmallTag{H}
31
+ end
32
+
33
+ @generated function tagcount (:: Type{SmallTag{H}} ) where {H}
34
+ :($ (Threads. atomic_add! (TAGCOUNT, UInt (1 ))))
35
+ end
36
+
37
+ function SmallTag (f:: F , :: Type{V} ) where {F,V}
38
+ H = if F <: Tuple
39
+ # no easy way to check Jacobian tag used with Hessians as multiple functions may be used
40
+ # see checktag(::Type{Tag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT<:Tuple,VT,F,V}
41
+ nothing
42
+ else
43
+ hash (F) ⊻ hash (V)
44
+ end
45
+ tagcount (SmallTag{H}) # trigger generated function
46
+ SmallTag {H} ()
47
+ end
48
+
49
+ SmallTag (:: Nothing , :: Type{V} ) where {V} = nothing
50
+
51
+ @inline function ≺ (:: Type{SmallTag{H1}} , :: Type{Tag{F2,V2}} ) where {H1,F2,V2}
52
+ tagcount (SmallTag{H1}) < tagcount (Tag{F2,V2})
53
+ end
54
+
55
+ @inline function ≺ (:: Type{Tag{F1,V1}} , :: Type{SmallTag{H2}} ) where {F1,V1,H2}
56
+ tagcount (Tag{F1,V1}) < tagcount (SmallTag{H2})
57
+ end
58
+
59
+ @inline function ≺ (:: Type{SmallTag{H1}} , :: Type{SmallTag{H2}} ) where {H1,H2}
60
+ tagcount (SmallTag{H1}) < tagcount (SmallTag{H2})
61
+ end
62
+
28
63
struct InvalidTagException{E,O} <: Exception
29
64
end
30
65
@@ -36,13 +71,22 @@ checktag(::Type{Tag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT,VT,F,V} =
36
71
37
72
checktag (:: Type{Tag{F,V}} , f:: F , x:: AbstractArray{V} ) where {F,V} = true
38
73
74
+ # SmallTag is a smaller tag, that only confirms the hash
75
+ function checktag (:: Type{SmallTag{HT}} , f:: F , x:: AbstractArray{V} ) where {HT,F,V}
76
+ H = hash (F) ⊻ hash (V)
77
+ if HT == H || HT === nothing
78
+ true
79
+ else
80
+ throw (InvalidTagException {SmallTag{H},SmallTag{HT}} ())
81
+ end
82
+ end
83
+
39
84
# no easy way to check Jacobian tag used with Hessians as multiple functions may be used
40
85
checktag (:: Type{Tag{FT,VT}} , f:: F , x:: AbstractArray{V} ) where {FT<: Tuple ,VT,F,V} = true
41
86
42
87
# custom tag: you're on your own.
43
88
checktag (z, f, x) = true
44
89
45
-
46
90
# #################
47
91
# AbstractConfig #
48
92
# #################
0 commit comments