-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Roe cleanup #161
base: compute-graph
Are you sure you want to change the base?
Roe cleanup #161
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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/
.
DEC/src/roe/RoeUtility.jl
Outdated
@@ -0,0 +1,222 @@ | |||
# """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should just be called "roe.jl" and be included into module.jl with no surrounding module?
DEC/src/roe/RoeUtility.jl
Outdated
|
||
Struct containing a Function and the vector of Sorts it requires. | ||
""" | ||
@struct_hash_equal struct TypedApplication |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This, and other things that have AbstractSort parameters, should be typed based on a subtype of AbstractSort.
DEC/src/roe/RoeUtility.jl
Outdated
|
||
""" 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add to this comment that fix_functions is used for the show method of Vars
DEC/src/roe/RoeUtility.jl
Outdated
|
||
""" 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
DEC/src/roe/SSAExtract.jl
Outdated
@@ -0,0 +1,137 @@ | |||
module SSAExtract |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just call this SSAs. And then all the things prefixed with SSA (i.e. SSAVar, etc.) can be SSAs.Var
, etc.
DEC/src/models/ThDEC/Signature.jl
Outdated
end | ||
end | ||
|
||
function ι(s1::Sort, s2::Sort) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either complete these or add TODO comments
DEC/src/models/ThDEC/EGraph.jl
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
DEC/src/models/ThDEC/Luke.jl
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
DEC/src/models/ThDEC/ThDEC.jl
Outdated
::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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
op = get(operator_lookup, TA(expr.head, first.(expr.args)), op)
DEC/src/models/ThDEC/ThDEC.jl
Outdated
export derivative_cost | ||
|
||
|
||
""" vfield :: (Decaroe -> (StateVars, ParamVars)) -> VectorFieldFunction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"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.
DEC/tests/DEC.jl
Outdated
|
||
# we can reuse the mesh and operator lookup | ||
_vf = vfield(new_heat_equation, operator_lookup) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TA(♭, Sort[DualVF()], Sort[Primal(1)]) => Decapodes.dec_♭(sd)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Und so weiter
|
||
""" | ||
function create_dynamic_model(sd, hodge)::Dict{TypedApplication, Any} | ||
Dict{TypedApplication, Any}( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Purposes of using a Dict here vs. an @match
block?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
No description provided.