Skip to content

Commit

Permalink
Try to explicitly heal invalidations
Browse files Browse the repository at this point in the history
  • Loading branch information
MilesCranmer committed Nov 21, 2023
1 parent c98958b commit 12ab7e4
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 43 deletions.
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ version = "0.9.0"
[deps]
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
PackageExtensionCompat = "65ce6f38-6b18-4e1d-a461-8949797d7930"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
Tricks = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775"

[weakdeps]
Expand All @@ -25,6 +26,7 @@ Aqua = "0.7"
Compat = "3.42, 4"
Measurements = "2"
PackageExtensionCompat = "1.0.2"
PrecompileTools = "1"
ScientificTypes = "3"
Tricks = "0.1"
Unitful = "1"
Expand Down
28 changes: 16 additions & 12 deletions src/math.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using PrecompileTools: @recompile_invalidations

for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES
div_base_type = type == AbstractGenericQuantity ? Number : base_type
@eval begin
Expand Down Expand Up @@ -75,18 +77,20 @@ Base.:/(l::AbstractDimensions, r::AbstractDimensions) = map_dimensions(-, l, r)
# Defines + and -
for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES, op in (:+, :-)
@eval begin
function Base.$op(l::$type, r::$type)
l, r = promote_except_value(l, r)
dimension(l) == dimension(r) || throw(DimensionError(l, r))
return new_quantity(typeof(l), $op(ustrip(l), ustrip(r)), dimension(l))
end
function Base.$op(l::$type, r::$base_type)
iszero(dimension(l)) || throw(DimensionError(l, r))
return new_quantity(typeof(l), $op(ustrip(l), r), dimension(l))
end
function Base.$op(l::$base_type, r::$type)
iszero(dimension(r)) || throw(DimensionError(l, r))
return new_quantity(typeof(r), $op(l, ustrip(r)), dimension(r))
@recompile_invalidations begin
function Base.$op(l::$type, r::$type)
l, r = promote_except_value(l, r)
dimension(l) == dimension(r) || throw(DimensionError(l, r))
return new_quantity(typeof(l), $op(ustrip(l), ustrip(r)), dimension(l))
end
function Base.$op(l::$type, r::$base_type)
iszero(dimension(l)) || throw(DimensionError(l, r))
return new_quantity(typeof(l), $op(ustrip(l), r), dimension(l))
end
function Base.$op(l::$base_type, r::$type)
iszero(dimension(r)) || throw(DimensionError(l, r))
return new_quantity(typeof(r), $op(l, ustrip(r)), dimension(r))
end
end
end
end
Expand Down
69 changes: 38 additions & 31 deletions src/utils.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Compat: allequal
using Compat: allequal
using PrecompileTools: @recompile_invalidations

function map_dimensions(f::F, args::AbstractDimensions...) where {F<:Function}
dimension_type = promote_type(typeof(args).parameters...)
Expand Down Expand Up @@ -26,7 +27,7 @@ end
end

for (type, base_type, _) in ABSTRACT_QUANTITY_TYPES
@eval Base.convert(::Type{$base_type}, q::$type) = q
@eval @recompile_invalidations Base.convert(::Type{$base_type}, q::$type) = q
end
function Base.convert(::Type{T}, q::UnionAbstractQuantity) where {T<:Number}
@assert iszero(dimension(q)) "$(typeof(q)): $(q) has dimensions! Use `ustrip` instead."
Expand Down Expand Up @@ -80,14 +81,16 @@ const AMBIGUOUS_NUMERIC_TYPES = (Bool, BigFloat)

for (type, _, _) in ABSTRACT_QUANTITY_TYPES
@eval begin
function Base.convert(::Type{Q}, x::BASE_NUMERIC_TYPES) where {T,D,Q<:$type{T,D}}
return new_quantity(Q, convert(T, x), D())
end
function Base.promote_rule(::Type{Q}, ::Type{T2}) where {T,D,Q<:$type{T,D},T2<:BASE_NUMERIC_TYPES}
return with_type_parameters(promote_quantity(Q, T2), promote_type(T, T2), D)
end
function Base.promote_rule(::Type{T2}, ::Type{Q}) where {T,D,Q<:$type{T,D},T2<:BASE_NUMERIC_TYPES}
return with_type_parameters(promote_quantity(Q, T2), promote_type(T, T2), D)
@recompile_invalidations begin
function Base.convert(::Type{Q}, x::BASE_NUMERIC_TYPES) where {T,D,Q<:$type{T,D}}
return new_quantity(Q, convert(T, x), D())
end
function Base.promote_rule(::Type{Q}, ::Type{T2}) where {T,D,Q<:$type{T,D},T2<:BASE_NUMERIC_TYPES}
return with_type_parameters(promote_quantity(Q, T2), promote_type(T, T2), D)
end
function Base.promote_rule(::Type{T2}, ::Type{Q}) where {T,D,Q<:$type{T,D},T2<:BASE_NUMERIC_TYPES}
return with_type_parameters(promote_quantity(Q, T2), promote_type(T, T2), D)
end
end
end
for numeric_type in AMBIGUOUS_NUMERIC_TYPES
Expand Down Expand Up @@ -158,32 +161,36 @@ for op in (:(<=), :(<), :(>=), :(>), :isless, :isgreater),
(type, base_type, _) in ABSTRACT_QUANTITY_TYPES

@eval begin
function Base.$(op)(l::$type, r::$type)
l, r = promote_except_value(l, r)
dimension(l) == dimension(r) || throw(DimensionError(l, r))
return $(op)(ustrip(l), ustrip(r))
end
function Base.$(op)(l::$type, r::$base_type)
iszero(dimension(l)) || throw(DimensionError(l, r))
return $(op)(ustrip(l), r)
end
function Base.$(op)(l::$base_type, r::$type)
iszero(dimension(r)) || throw(DimensionError(l, r))
return $(op)(l, ustrip(r))
@recompile_invalidations begin
function Base.$(op)(l::$type, r::$type)
l, r = promote_except_value(l, r)
dimension(l) == dimension(r) || throw(DimensionError(l, r))
return $(op)(ustrip(l), ustrip(r))
end
function Base.$(op)(l::$type, r::$base_type)
iszero(dimension(l)) || throw(DimensionError(l, r))
return $(op)(ustrip(l), r)
end
function Base.$(op)(l::$base_type, r::$type)
iszero(dimension(r)) || throw(DimensionError(l, r))
return $(op)(l, ustrip(r))
end
end
end
end
for op in (:isequal, :(==)), (type, base_type, _) in ABSTRACT_QUANTITY_TYPES
@eval begin
function Base.$(op)(l::$type, r::$type)
l, r = promote_except_value(l, r)
return $(op)(ustrip(l), ustrip(r)) && dimension(l) == dimension(r)
end
function Base.$(op)(l::$type, r::$base_type)
return $(op)(ustrip(l), r) && iszero(dimension(l))
end
function Base.$(op)(l::$base_type, r::$type)
return $(op)(l, ustrip(r)) && iszero(dimension(r))
@recompile_invalidations begin
function Base.$(op)(l::$type, r::$type)
l, r = promote_except_value(l, r)
return $(op)(ustrip(l), ustrip(r)) && dimension(l) == dimension(r)
end
function Base.$(op)(l::$type, r::$base_type)
return $(op)(ustrip(l), r) && iszero(dimension(l))
end
function Base.$(op)(l::$base_type, r::$type)
return $(op)(l, ustrip(r)) && iszero(dimension(r))
end
end
end
end
Expand Down

0 comments on commit 12ab7e4

Please sign in to comment.