Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d878703
Optimize ENode memory management with an optional pooling mechanism
jonathanvdc Nov 9, 2025
4435469
Refactor ENode array allocation to use dedicated delegates
jonathanvdc Nov 9, 2025
55b89b1
Specify type for pooled ENode acquisition in ENodePoolTest
jonathanvdc Nov 9, 2025
41883a1
Enhance CommandScheduleBuilder and PatternApplier to utilize ENode po…
jonathanvdc Nov 9, 2025
c405cee
Add methods to acquire and fill slot and call arrays from the pool
jonathanvdc Nov 9, 2025
824cd25
Refactor candidate node acquisition to use acquireUnsafe and fill slo…
jonathanvdc Nov 9, 2025
1e97592
Optimize memory management by replacing HashMap with fixed-size array…
jonathanvdc Nov 9, 2025
98bc093
Update symbolArrayFrom to utilize ENode pool for memory-efficient arr…
jonathanvdc Nov 9, 2025
5f458a6
Refactor CommandScheduleBuilder and PatternApplier to utilize IntRef …
jonathanvdc Nov 9, 2025
7b096da
Limit IntRef pool size to 64 for improved memory management and cache…
jonathanvdc Nov 9, 2025
10caa18
Implement object pooling for SimplifiedAddCommandInstantiator to enha…
jonathanvdc Nov 9, 2025
4fce083
Remove unused import in PatternApplier.scala to clean up code
jonathanvdc Nov 9, 2025
a89c67b
Refactor MutableMachineState to replace MixedTree with EClassCall for…
jonathanvdc Nov 9, 2025
3123741
Refactor ApplierOps to use bind method for variable substitution
jonathanvdc Nov 9, 2025
74deae8
Introduce specialized CallTree type
jonathanvdc Nov 9, 2025
7e99429
Comment out array nullification in ENode to optimize memory management
jonathanvdc Nov 9, 2025
e66401b
Add AbstractPatternMatch trait and refactor PatternMatch to extend it
jonathanvdc Nov 9, 2025
fba9860
Refactor PatternMatch and PatternApplier to use AbstractPatternMatch …
jonathanvdc Nov 9, 2025
5f2ba34
Extend MutableMachineState to implement AbstractPatternMatch and add …
jonathanvdc Nov 9, 2025
89acdc0
Add searchBorrowed method to CompiledPattern for e-graph pattern matc…
jonathanvdc Nov 9, 2025
3491f30
Add StateBorrowingMachineEClassSearcher for efficient pattern matchin…
jonathanvdc Nov 9, 2025
dc8c86b
Add borrowing searcher and rules for pattern matching in e-graphs
jonathanvdc Nov 9, 2025
c34f93f
Refactor Rules to use AbstractPatternMatch and state-borrowing rules
jonathanvdc Nov 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ object ApplierOps {

def subst(tree: ArithExpr): ArithExpr = {
tree match {
case Var(slot) if slot == m(from) => L.fromTree[EClassCall](m(to.variable))
case Var(slot) if slot == m(from) => L.fromTree(m(to.variable))
case Var(slot) => Var(slot)
case Lam(param, body) => Lam(param, subst(body))
case App(fun, arg) => App(subst(fun), subst(arg))
Expand All @@ -46,7 +46,7 @@ object ApplierOps {
}

val substituted = subst(extractedExpr)
val newMatch = m.copy(varMapping = m.varMapping + (destination.variable -> L.toTree[EClassCall](substituted)))
val newMatch = m.bind(destination.variable, L.toCallTree(substituted))
applier.apply(newMatch, egraph, builder)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ final case class Rules()(using L: Language[ArithExpr]) {
result.toSeq.map { value =>
// If a constant value is found, create a new Number node and bind it to the variable, overwriting the
// original binding.
subst.bind(x.variable, L.toTree(Number(value)))
subst.bind(x.variable, L.toCallTree(Number(value)))
}
}),
L.toApplier(x)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package foresight.eqsat.examples.mm
import foresight.eqsat.lang.{Language, LanguageOp}
import foresight.eqsat.readonly.EGraph
import foresight.eqsat.rewriting.Rule
import foresight.eqsat.rewriting.patterns.PatternMatch
import foresight.eqsat.rewriting.patterns.AbstractPatternMatch

import scala.language.implicitConversions

Expand All @@ -13,17 +13,17 @@ import scala.language.implicitConversions
final case class Rules()(using L: Language[LinalgExpr]) {
type Op = LanguageOp[LinalgExpr]
type LinalgEGraph = EGraph[LinalgIR]
type LinalgRule = Rule[LinalgIR, PatternMatch[LinalgIR], LinalgEGraph]
type LinalgRule = Rule[LinalgIR, AbstractPatternMatch[LinalgIR], LinalgEGraph]

import L.rule
import L.borrowingRule

val matMulAssociativity1: LinalgRule =
rule("mul-associativity1") { (x, y, z) =>
borrowingRule("mul-associativity1") { (x, y, z) =>
((x * y) * z) -> (x * (y * z))
}

val matMulAssociativity2: LinalgRule =
rule("mul-associativity2") { (x, y, z) =>
borrowingRule("mul-associativity2") { (x, y, z) =>
(x * (y * z)) -> ((x * y) * z)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ object ApplierOps {
override def apply(m: PatternMatch[ArithIR], egraph: EGraphWithMetadata[ArithIR, EGraphT], builder: CommandScheduleBuilder[ArithIR]): Unit = {
val extracted = ExtractionAnalysis.smallest[ArithIR].extractor[EGraphT](m(source), egraph)

def subst(tree: Tree[ArithIR]): MixedTree[ArithIR, EClassCall] = {
def subst(tree: Tree[ArithIR]): CallTree[ArithIR] = {
tree match {
case Tree(Var, Seq(), Seq(use), Seq()) if use == m(from) => m(to)
case Tree(nodeType, defs, uses, args) =>
MixedTree.Node(nodeType, defs, uses, args.map(subst))
CallTree.Node(nodeType, defs, uses, args.map(subst))
}
}

val substituted = subst(extracted)
val newMatch = m.copy(varMapping = m.varMapping + (destination -> substituted))
val newMatch = m.bind(destination, substituted)
applier.apply(newMatch, egraph, builder)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import foresight.eqsat.examples.arith.ApplierOps._
import foresight.eqsat.readonly.{EGraph, EGraphWithMetadata}
import foresight.eqsat.rewriting.Rule
import foresight.eqsat.rewriting.patterns.{Pattern, PatternMatch}
import foresight.eqsat.{MixedTree, Slot}
import foresight.eqsat.{CallTree, MixedTree, Slot}

/**
* This object contains a collection of rules for rewriting arithmetic expressions.
Expand Down Expand Up @@ -63,7 +63,7 @@ object Rules {
result.toSeq.map { value =>
// If a constant value is found, create a new Number node and bind it to the variable, overwriting the
// original binding.
subst.bind(x, Number(value))
subst.bind(x, CallTree.from(Number(value)))
}
}),
MixedTree.Atom[ArithIR, Pattern.Var](x).toApplier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,23 @@ object ApplierOps {
override def apply(m: PatternMatch[ArrayIR], egraph: EGraphWithMetadata[ArrayIR, EGraphT], builder: CommandScheduleBuilder[ArrayIR]): Unit = {
val extracted = ExtractionAnalysis.smallest[ArrayIR].extractor[EGraphT](m(source), egraph)

def typeOf(tree: MixedTree[ArrayIR, EClassCall]): MixedTree[Type, EClassCall] = {
TypeInferenceAnalysis.get(egraph)(tree, egraph)
def typeOf(tree: CallTree[ArrayIR]): CallTree[Type] = {
CallTree.from(TypeInferenceAnalysis.get(egraph)(tree, egraph))
}

def subst(tree: Tree[ArrayIR]): MixedTree[ArrayIR, EClassCall] = {
def subst(tree: Tree[ArrayIR]): CallTree[ArrayIR] = {
tree match {
case Tree(Var, Seq(), Seq(use), Seq(fromType))
if use == m(from) && typeOf(m(to)) == MixedTree.fromTree(fromType) =>
if use == m(from) && typeOf(m(to)) == CallTree.from(fromType) =>

m(to)
case Tree(nodeType, defs, uses, args) =>
MixedTree.Node(nodeType, defs, uses, args.map(subst))
CallTree.Node(nodeType, defs, uses, args.map(subst))
}
}

val substituted = subst(extracted)
val newMatch = m.copy(varMapping = m.varMapping + (destination -> substituted))
val newMatch = m.bind(destination, substituted)
applier.apply(newMatch, egraph, builder)
}
}
Expand All @@ -66,7 +66,7 @@ object ApplierOps {
val tree = applier.instantiate(m)
val realTree = tree.mapAtoms(_.asInstanceOf[EClassCall])
inferType(realTree, egraph)
val c = builder.addSimplifiedReal(realTree, egraph)
val c = builder.addSimplifiedReal(CallTree.from(realTree), egraph)
builder.unionSimplified(EClassSymbol.real(m.root), c, egraph)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import foresight.eqsat.examples.liar.TypeRequirements.RequirementsSearcherContin
import foresight.eqsat.parallel.ParallelMap
import foresight.eqsat.rewriting.patterns.{CompiledPattern, Pattern, PatternMatch}
import foresight.eqsat.rewriting.{Applier, ReversibleSearcher, Searcher}
import foresight.eqsat.MixedTree
import foresight.eqsat.{CallTree, EClassCall, MixedTree}
import foresight.eqsat.immutable.{EGraph, EGraphLike, EGraphWithMetadata}

object SearcherOps {
Expand All @@ -23,8 +23,8 @@ object SearcherOps {
searcher.map((m, egraph) => {
val newVarMapping = m.varMapping ++ types.map {
case (value, t) =>
val (call, newEGraph) = egraph.add(m(value))
t -> TypeInferenceAnalysis.get(newEGraph)(call, newEGraph)
val (call, newEGraph) = egraph.add(m(value).toMixedTree)
t -> CallTree.from(TypeInferenceAnalysis.get(newEGraph)(call, newEGraph))
}
PatternMatch(m.root, newVarMapping, m.slotMapping)
})
Expand Down Expand Up @@ -53,8 +53,8 @@ object SearcherOps {
searcher.filter((m, egraph) => {
values.forall(v => {
m(v) match {
case MixedTree.Atom(c) => egraph.nodes(c).head.nodeType.isInstanceOf[Value]
case MixedTree.Node(nodeType, _, _, _) => nodeType.isInstanceOf[Value]
case c: EClassCall => egraph.nodes(c).head.nodeType.isInstanceOf[Value]
case CallTree.Node(nodeType, _, _, _) => nodeType.isInstanceOf[Value]
}
})
})
Expand All @@ -69,8 +69,8 @@ object SearcherOps {
def requireNonFunctionType(t: Pattern.Var): Searcher[ArrayIR, PatternMatch[ArrayIR], EGraphT] = {
searcher.filter((m, egraph) => {
m(t) match {
case MixedTree.Atom(c) => egraph.nodes(c).head.nodeType != FunctionType
case MixedTree.Node(nodeType, _, _, _) => nodeType != FunctionType
case c: EClassCall => egraph.nodes(c).head.nodeType != FunctionType
case CallTree.Node(nodeType, _, _, _) => nodeType != FunctionType
}
})
}
Expand All @@ -83,8 +83,8 @@ object SearcherOps {
def requireInt32Type(t: Pattern.Var): Searcher[ArrayIR, PatternMatch[ArrayIR], EGraphT] = {
searcher.filter((m, egraph) => {
m(t) match {
case MixedTree.Atom(c) => egraph.nodes(c).head.nodeType == Int32Type
case MixedTree.Node(nodeType, _, _, _) => nodeType == Int32Type
case c: EClassCall => egraph.nodes(c).head.nodeType == Int32Type
case CallTree.Node(nodeType, _, _, _) => nodeType == Int32Type
}
})
}
Expand All @@ -97,8 +97,8 @@ object SearcherOps {
def requireDoubleType(t: Pattern.Var): Searcher[ArrayIR, PatternMatch[ArrayIR], EGraphT] = {
searcher.filter((m, egraph) => {
m(t) match {
case MixedTree.Atom(c) => egraph.nodes(c).head.nodeType == DoubleType
case MixedTree.Node(nodeType, _, _, _) => nodeType == DoubleType
case c: EClassCall => egraph.nodes(c).head.nodeType == DoubleType
case CallTree.Node(nodeType, _, _, _) => nodeType == DoubleType
}
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ object ApplierOps {
override def apply(m: PatternMatch[SdqlIR], egraph: EGraphWithMetadata[SdqlIR, EGraphT], builder: CommandScheduleBuilder[SdqlIR]): Unit = {
val extracted = ExtractionAnalysis.smallest[SdqlIR].extractor[EGraphT](m(source), egraph)

def subst(tree: Tree[SdqlIR]): MixedTree[SdqlIR, EClassCall] = {
def subst(tree: Tree[SdqlIR]): CallTree[SdqlIR] = {
tree match {
case Tree(Var, Seq(), Seq(use), Seq()) if use == m(from) => m(to)
case Tree(nodeType, defs, uses, args) =>
MixedTree.Node(nodeType, defs, uses, args.map(subst))
CallTree.Node(nodeType, defs, uses, args.map(subst))
}
}

val substituted = subst(extracted)
val newMatch = m.copy(varMapping = m.varMapping + (destination -> substituted))
val newMatch = m.bind(destination, substituted)
applier.apply(newMatch, egraph, builder)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package foresight.eqsat.examples.mm

import foresight.eqsat.examples.mm.{Fact, LinalgExpr, LinalgIR, Mat, Mul, Rules, *}
import foresight.eqsat.lang._
import foresight.eqsat.saturation.{MaximalRuleApplication, MaximalRuleApplicationWithCaching, Strategy}
import foresight.eqsat.saturation.{MaximalRuleApplication, Strategy}
import foresight.eqsat.EClassCall
import foresight.eqsat.immutable.EGraph
import foresight.eqsat.mutable
Expand Down
Loading