From 593d9e26f1ba37790d77b054f29fd2ac8b6dfc59 Mon Sep 17 00:00:00 2001 From: Gabriel Kronberger Date: Wed, 21 Aug 2024 17:01:53 +0200 Subject: [PATCH] Global counters for VecExpr hash access. --- src/EGraphs/egraph.jl | 8 ++++++++ src/vecexpr.jl | 23 ++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/EGraphs/egraph.jl b/src/EGraphs/egraph.jl index f645e44a..f63c99c3 100644 --- a/src/EGraphs/egraph.jl +++ b/src/EGraphs/egraph.jl @@ -250,10 +250,14 @@ function canonicalize!(g::EGraph, n::VecExpr) n end +memo_lookups = 0 +memo_add = 0 + function lookup(g::EGraph, n::VecExpr)::Id canonicalize!(g, n) h = IdKey(v_hash(n)) + global memo_lookups += 1 haskey(g.memo, n) ? find(g, g.memo[n]) : 0 end @@ -273,6 +277,7 @@ Inserts an e-node in an [`EGraph`](@ref) function add!(g::EGraph{ExpressionType,Analysis}, n::VecExpr, should_copy::Bool)::Id where {ExpressionType,Analysis} canonicalize!(g, n) + global memo_lookups += 1 haskey(g.memo, n) && return g.memo[n] if should_copy @@ -287,6 +292,7 @@ function add!(g::EGraph{ExpressionType,Analysis}, n::VecExpr, should_copy::Bool) end end + global memo_add += 1 g.memo[n] = id add_class_by_op(g, n, id) @@ -431,8 +437,10 @@ function process_unions!(g::EGraph{ExpressionType,AnalysisType})::Int where {Exp while !isempty(g.pending) (node::VecExpr, eclass_id::Id) = pop!(g.pending) canonicalize!(g, node) + global memo_lookups += 1 if haskey(g.memo, node) old_class_id = g.memo[node] + global memo_add += 1 g.memo[node] = eclass_id did_something = union!(g, old_class_id, eclass_id) # TODO unique! can node dedup be moved here? compare performance diff --git a/src/vecexpr.jl b/src/vecexpr.jl index 1e8a83ba..9b6ae27e 100644 --- a/src/vecexpr.jl +++ b/src/vecexpr.jl @@ -28,6 +28,8 @@ export Id, const Id = UInt64 +vexpr_created = 0 + """ struct VecExpr data::Vector{Id} @@ -45,6 +47,11 @@ The hash value for the VecExpr is cached in the first position for faster lookup """ struct VecExpr data::Vector{Id} + + function VecExpr(data) + global vexpr_created += 1 + new(data) + end end const VECEXPR_FLAG_ISTREE = 0x01 @@ -65,26 +72,33 @@ const VECEXPR_META_LENGTH = 4 """Number of children in the e-node.""" @inline v_arity(n::VecExpr)::Int = length(n.data) - VECEXPR_META_LENGTH + +cached_hash_access = 0 +cached_hash_computation = 0 """ Compute the hash of a `VecExpr` and store it as the first element. """ @inline function v_hash!(n::VecExpr)::Id if iszero(n.data[1]) n.data[1] = hash(@view n.data[2:end]) + global cached_hash_computation += 1 else + global cached_hash_access += 1 # h = hash(@view n[2:end]) # @assert h == n[1] n.data[1] end end +hash_calls = 0 """The hash of the e-node.""" -@inline v_hash(n::VecExpr)::Id = @inbounds n.data[1] +@inline v_hash(n::VecExpr)::Id = begin global hash_calls += 1; @inbounds n.data[1] end Base.hash(n::VecExpr) = v_hash(n) # IdKey not necessary here Base.:(==)(a::VecExpr, b::VecExpr) = (@view a.data[2:end]) == (@view b.data[2:end]) """Set e-node hash to zero.""" -@inline v_unset_hash!(n::VecExpr)::Id = @inbounds (n.data[1] = Id(0)) +unset_hash_calls = 0 +@inline v_unset_hash!(n::VecExpr)::Id = begin global unset_hash_calls += 1; @inbounds (n.data[1] = Id(0)) end """E-class IDs of the children of the e-node.""" @inline v_children(n::VecExpr) = @view n.data[(VECEXPR_META_LENGTH + 1):end] @@ -99,8 +113,11 @@ Base.:(==)(a::VecExpr, b::VecExpr) = (@view a.data[2:end]) == (@view b.data[2:en "Update the E-Node operation ID." @inline v_set_head!(n::VecExpr, h::Id) = @inbounds (n.data[VECEXPR_META_LENGTH] = h) +v_new_calls = 0 +v_copy_calls = 0 """Construct a new, empty `VecExpr` with `len` children.""" @inline function v_new(len::Int)::VecExpr + global v_new_calls += 1 n = VecExpr(Vector{Id}(undef, len + VECEXPR_META_LENGTH)) v_unset_hash!(n) v_unset_flags!(n) @@ -117,7 +134,7 @@ v_pair_last(p::UInt128)::UInt64 = UInt64(p & 0xffffffffffffffff) @inline Base.length(n::VecExpr) = length(n.data) @inline Base.getindex(n::VecExpr, i) = n.data[i] @inline Base.setindex!(n::VecExpr, val, i) = n.data[i] = val -@inline Base.copy(n::VecExpr) = VecExpr(copy(n.data)) +@inline Base.copy(n::VecExpr) = begin global v_copy_calls += 1; VecExpr(copy(n.data)) end @inline Base.lastindex(n::VecExpr) = lastindex(n.data) @inline Base.firstindex(n::VecExpr) = firstindex(n.data)