Roe cleanup#161
Conversation
olynch
left a comment
There was a problem hiding this comment.
General comments:
- We should not be using the GATlab nomenclature of
ThDEC/models, to avoid confusion - Let's try to make folder structure of
test/mimic the folder structure ofsrc/.
| @@ -0,0 +1,222 @@ | |||
| # """ | |||
There was a problem hiding this comment.
Maybe this should just be called "roe.jl" and be included into module.jl with no surrounding module?
|
|
||
| Struct containing a Function and the vector of Sorts it requires. | ||
| """ | ||
| @struct_hash_equal struct TypedApplication |
There was a problem hiding this comment.
This, and other things that have AbstractSort parameters, should be typed based on a subtype of AbstractSort.
|
|
||
| """ fix_functions(e)::Union{Symbol, Expr} | ||
|
|
||
| Traverses the AST of an expression, replacing the head of :call expressions to its name, a Symbol. |
There was a problem hiding this comment.
Add to this comment that fix_functions is used for the show method of Vars
|
|
||
| """ fresh!(roe::Roe, sort::AbstractSort, name::Symbol)::Var{sort} | ||
|
|
||
| Creates a new ("fresh") variable in a Roe given a sort and a name. |
There was a problem hiding this comment.
Should be something like:
Creates a new variable in a Roe. Specifically, appends a new RootVar with given sort and name to the Roe, adds that RootVar to the e-graph, and returns a Var wrapper around the new e-graph id, with type parameter given by the sort.
| @@ -0,0 +1,137 @@ | |||
| module SSAExtract | |||
There was a problem hiding this comment.
Maybe just call this SSAs. And then all the things prefixed with SSA (i.e. SSAVar, etc.) can be SSAs.Var, etc.
| end | ||
| end | ||
|
|
||
| function ι(s1::Sort, s2::Sort) |
There was a problem hiding this comment.
Either complete these or add TODO comments
| import Base: +, -, * | ||
|
|
||
| # These operations create calls on a common egraph. We validate the signature by dispatching the operation on the types using methods we defined in Signature. | ||
|
|
There was a problem hiding this comment.
for binop in [+, *, -, \wedge, ...]
@eval begin
function $binop(v1::Var{s1}, v2::Var{s2}) where {s1, s2}
v1.roe === v2.roe || error("Cannot add variables from different graphs")
s = $binop(s1, s2)
Var{s}(v1.roe, addcall!(v1.roe.graph, $binop, (v1.id, v2.id)))
end
export $binop
end
endThere was a problem hiding this comment.
This might be the blessed way to do it (also add the overloads with Number) -- we should doublecheck that this will run during precompilation though!
There was a problem hiding this comment.
This looks fine to me. Julia's Base does this for op in [+,*...] a lot to define all the possible methods between different numeric types.
| Given a matrix and a hodge star (DiagonalHodge() or GeometricHodge()), this returns a lookup dictionary between operators (as TypedApplications) and their corresponding matrices. | ||
|
|
||
| """ | ||
| function precompute_matrices(sd, hodge)::Dict{TypedApplication, Any} |
There was a problem hiding this comment.
Maybe this should be called something more generic, like "create_dynamic_model" or something? Basically, what this is doing is creating a Dict that stores a model of the theory of DEC. We can workshop that name though.
| ::RootVar => rootvar_lookup[expr.head] | ||
| ::Number => expr.head | ||
| _ => begin | ||
| op = operator_lookup[TA(expr.head, first.(expr.args))] |
There was a problem hiding this comment.
op = get(operator_lookup, TA(expr.head, first.(expr.args)), op)| export derivative_cost | ||
|
|
||
|
|
||
| """ vfield :: (Decaroe -> (StateVars, ParamVars)) -> VectorFieldFunction |
There was a problem hiding this comment.
Right now this is hacked to assume that there only one state variable and only one parameter variable, because we haven't integrated with ComponentArrays yet: we should integrate with ComponentArrays.
There was a problem hiding this comment.
"integrating with ComponentArrays" should just mean that you assume the state variable and parameter variables can be accessed by symbolic keys, and that what you get back from indexing will be either a vector or a scalar value so you use broadcasted operations when necessary.
It is a pretty light lift from the users perspective.
| end | ||
|
|
||
| # we can reuse the mesh and operator lookup | ||
| _vf = vfield(new_heat_equation, operator_lookup) |
There was a problem hiding this comment.
this one won't run for me
_vf = vfield(new_heat_equation, operator_lookup) # XXX: brooken
ERROR: KeyError: key Scalar() * PrimalForm(0) not found
Stacktrace:
[1] getindex
@ ./dict.jl:477 [inlined]
[2] (::DEC.Models.ThDEC.var"#toexpr#15"{Dict{TypedApplication, Any}, Dict{RootVar, Union{Expr, Symbol}}})(expr::SSAExpr)
@ DEC.Models.ThDEC ~/.julia/dev/GATlab/DEC/src/models/ThDEC/ThDEC.jl:97
[3] (::DEC.Models.ThDEC.var"#7#17")(::Any)
@ DEC.Models.ThDEC ~/.julia/dev/GATlab/DEC/src/models/ThDEC/ThDEC.jl:126
[4] iterate
@ ./generator.jl:48 [inlined]
[5] collect_to!
@ ./array.jl:838 [inlined]
[6] collect_to_with_first!
@ ./array.jl:816 [inlined]
[7] collect(itr::Base.Generator{Base.Iterators.Enumerate{Vector{SSAExpr}}, DEC.Models.ThDEC.var"#7#17"})
@ Base ./array.jl:790
[8] map
@ ./abstractarray.jl:3402 [inlined]
[9] vfield(model::Any, operator_lookup::Dict{TypedApplication, Any})
@ DEC.Models.ThDEC ~/.julia/dev/GATlab/DEC/src/models/ThDEC/ThDEC.jl:125
[10] top-level scope
@ REPL[26]:1
There was a problem hiding this comment.
Right, @olynch and I reviewed this today and decided we need to just tweak the code to use Julia's * operation. This and the other comments should be resolved tomorrow
|
High level thought @olynch, we discussed on Thursday in lab meeting that the Roe stuff is just based on Metatheory.jl so it doesn't really need Gatlab integration yet. Should this PR end up in DiagrammaticEquations.jl? |
That’d be sick if it’s reasonable |
| # :Δᵈ₁ => Δᵈ(Val{1},sd) | ||
|
|
||
| # # Musical Isomorphisms | ||
| TA(♯, Sort[PrimalForm(1)]) => Decapodes.dec_♯_p(sd), # Primal(1) -> PVField |
There was a problem hiding this comment.
As discussed on Zulip and offline, this dict needs to be refactored to emit functions based on input and output types both. This is to accommodate e.g. the fact that there is a
There was a problem hiding this comment.
At this level, the output type is determined by the input types, so I'm not really sure what this means.
There was a problem hiding this comment.
In the DEC, an e.g. sharp operator can be defined which takes a primal form and outputs a primal vector field, while another sharp operator takes a primal form and emits a dual vector field. Both of these can coexist.
The appearance of dual complexes leads to a proliferation of the operators in the discrete theory. For example there are
primal-primal, primal-dual etc. versions of many operators. This is of course unique to the discrete side.
From hirani
| function TypedApplication(head::Function, sorts::Vector{Sort}) where Sort | ||
| new{Sort}(head, sorts) | ||
| end | ||
| end |
There was a problem hiding this comment.
@struct_hash_equal struct TypedApplication{Sort<:AbstractSort}
head::Function
insorts::Vector{Sort}
outsorts::Vector{Sort}
function TypedApplication(head::Function, sorts::Vector{Sort}) where Sort
new{Sort}(head, sorts)
end
end| TA(♯, Sort[PrimalForm(1)]) => Decapodes.dec_♯_p(sd), # Primal(1) -> PVField | ||
| TA(♯, Sort[DualForm(1)]) => Decapodes.dec_♯_d(sd), # Dual(1) -> DVField | ||
|
|
||
| TA(♭, Sort[DualVF()]) => Decapodes.dec_♭(sd), # DVField -> Primal(1) |
There was a problem hiding this comment.
TA(♭, Sort[DualVF()], Sort[Primal(1)]) => Decapodes.dec_♭(sd)|
|
||
| """ | ||
| function create_dynamic_model(sd, hodge)::Dict{TypedApplication, Any} | ||
| Dict{TypedApplication, Any}( |
There was a problem hiding this comment.
We need to special-case sums of more than 32 forms.
We need to not do sums two-at-a-time.
| Given a matrix and a hodge star (DiagonalHodge() or GeometricHodge()), this returns a lookup dictionary between operators (as TypedApplications) and their corresponding matrices. | ||
|
|
||
| """ | ||
| function create_dynamic_model(sd, hodge)::Dict{TypedApplication, Any} |
There was a problem hiding this comment.
Purposes of using a Dict here vs. an @match block?
There was a problem hiding this comment.
I think the blessed way to do this is going to actually be to create a memoized function/lazy dict. Best of both worlds: we don't have to compute operators that we don't need, and we don't have to compute operators multiple times.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## compute-graph #161 +/- ##
==============================================
Coverage 84.37% 84.37%
==============================================
Files 42 42
Lines 2873 2873
==============================================
Hits 2424 2424
Misses 449 449 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
No description provided.