Rework graph state
This commit is contained in:
parent
669444ebbd
commit
80a3912e3e
@ -4,82 +4,82 @@ function main()
|
||||
graph = DAG()
|
||||
|
||||
# s to output (exit node)
|
||||
d_exit = insert_node(graph, make_node(DataTask(10)))
|
||||
d_exit = insert_node!(graph, make_node(DataTask(10)))
|
||||
|
||||
# final s compute
|
||||
s0 = insert_node(graph, make_node(ComputeTaskS2()))
|
||||
s0 = insert_node!(graph, make_node(ComputeTaskS2()))
|
||||
|
||||
# data from v0 and v1 to s0
|
||||
d_v0_s0 = insert_node(graph, make_node(DataTask(5)))
|
||||
d_v1_s0 = insert_node(graph, make_node(DataTask(5)))
|
||||
d_v0_s0 = insert_node!(graph, make_node(DataTask(5)))
|
||||
d_v1_s0 = insert_node!(graph, make_node(DataTask(5)))
|
||||
|
||||
# v0 and v1 compute
|
||||
v0 = insert_node(graph, make_node(ComputeTaskV()))
|
||||
v1 = insert_node(graph, make_node(ComputeTaskV()))
|
||||
v0 = insert_node!(graph, make_node(ComputeTaskV()))
|
||||
v1 = insert_node!(graph, make_node(ComputeTaskV()))
|
||||
|
||||
# data from uB, uA, uBp and uAp to v0 and v1
|
||||
d_uB_v0 = insert_node(graph, make_node(DataTask(3)))
|
||||
d_uA_v0 = insert_node(graph, make_node(DataTask(3)))
|
||||
d_uBp_v1 = insert_node(graph, make_node(DataTask(3)))
|
||||
d_uAp_v1 = insert_node(graph, make_node(DataTask(3)))
|
||||
d_uB_v0 = insert_node!(graph, make_node(DataTask(3)))
|
||||
d_uA_v0 = insert_node!(graph, make_node(DataTask(3)))
|
||||
d_uBp_v1 = insert_node!(graph, make_node(DataTask(3)))
|
||||
d_uAp_v1 = insert_node!(graph, make_node(DataTask(3)))
|
||||
|
||||
# uB, uA, uBp and uAp computes
|
||||
uB = insert_node(graph, make_node(ComputeTaskU()))
|
||||
uA = insert_node(graph, make_node(ComputeTaskU()))
|
||||
uBp = insert_node(graph, make_node(ComputeTaskU()))
|
||||
uAp = insert_node(graph, make_node(ComputeTaskU()))
|
||||
uB = insert_node!(graph, make_node(ComputeTaskU()))
|
||||
uA = insert_node!(graph, make_node(ComputeTaskU()))
|
||||
uBp = insert_node!(graph, make_node(ComputeTaskU()))
|
||||
uAp = insert_node!(graph, make_node(ComputeTaskU()))
|
||||
|
||||
# data from PB, PA, PBp and PAp to uB, uA, uBp and uAp
|
||||
d_PB_uB = insert_node(graph, make_node(DataTask(6)))
|
||||
d_PA_uA = insert_node(graph, make_node(DataTask(6)))
|
||||
d_PBp_uBp = insert_node(graph, make_node(DataTask(6)))
|
||||
d_PAp_uAp = insert_node(graph, make_node(DataTask(6)))
|
||||
d_PB_uB = insert_node!(graph, make_node(DataTask(6)))
|
||||
d_PA_uA = insert_node!(graph, make_node(DataTask(6)))
|
||||
d_PBp_uBp = insert_node!(graph, make_node(DataTask(6)))
|
||||
d_PAp_uAp = insert_node!(graph, make_node(DataTask(6)))
|
||||
|
||||
# P computes PB, PA, PBp and PAp
|
||||
PB = insert_node(graph, make_node(ComputeTaskP()))
|
||||
PA = insert_node(graph, make_node(ComputeTaskP()))
|
||||
PBp = insert_node(graph, make_node(ComputeTaskP()))
|
||||
PAp = insert_node(graph, make_node(ComputeTaskP()))
|
||||
PB = insert_node!(graph, make_node(ComputeTaskP()))
|
||||
PA = insert_node!(graph, make_node(ComputeTaskP()))
|
||||
PBp = insert_node!(graph, make_node(ComputeTaskP()))
|
||||
PAp = insert_node!(graph, make_node(ComputeTaskP()))
|
||||
|
||||
# entry nodes getting data for P computes
|
||||
d_PB = insert_node(graph, make_node(DataTask(4)))
|
||||
d_PA = insert_node(graph, make_node(DataTask(4)))
|
||||
d_PBp = insert_node(graph, make_node(DataTask(4)))
|
||||
d_PAp = insert_node(graph, make_node(DataTask(4)))
|
||||
d_PB = insert_node!(graph, make_node(DataTask(4)))
|
||||
d_PA = insert_node!(graph, make_node(DataTask(4)))
|
||||
d_PBp = insert_node!(graph, make_node(DataTask(4)))
|
||||
d_PAp = insert_node!(graph, make_node(DataTask(4)))
|
||||
|
||||
# now for all the edgese
|
||||
insert_edge(graph, make_edge(d_PB, PB))
|
||||
insert_edge(graph, make_edge(d_PA, PA))
|
||||
insert_edge(graph, make_edge(d_PBp, PBp))
|
||||
insert_edge(graph, make_edge(d_PAp, PAp))
|
||||
insert_edge!(graph, make_edge(d_PB, PB))
|
||||
insert_edge!(graph, make_edge(d_PA, PA))
|
||||
insert_edge!(graph, make_edge(d_PBp, PBp))
|
||||
insert_edge!(graph, make_edge(d_PAp, PAp))
|
||||
|
||||
insert_edge(graph, make_edge(PB, d_PB_uB))
|
||||
insert_edge(graph, make_edge(PA, d_PA_uA))
|
||||
insert_edge(graph, make_edge(PBp, d_PBp_uBp))
|
||||
insert_edge(graph, make_edge(PAp, d_PAp_uAp))
|
||||
insert_edge!(graph, make_edge(PB, d_PB_uB))
|
||||
insert_edge!(graph, make_edge(PA, d_PA_uA))
|
||||
insert_edge!(graph, make_edge(PBp, d_PBp_uBp))
|
||||
insert_edge!(graph, make_edge(PAp, d_PAp_uAp))
|
||||
|
||||
insert_edge(graph, make_edge(d_PB_uB, uB))
|
||||
insert_edge(graph, make_edge(d_PA_uA, uA))
|
||||
insert_edge(graph, make_edge(d_PBp_uBp, uBp))
|
||||
insert_edge(graph, make_edge(d_PAp_uAp, uAp))
|
||||
insert_edge!(graph, make_edge(d_PB_uB, uB))
|
||||
insert_edge!(graph, make_edge(d_PA_uA, uA))
|
||||
insert_edge!(graph, make_edge(d_PBp_uBp, uBp))
|
||||
insert_edge!(graph, make_edge(d_PAp_uAp, uAp))
|
||||
|
||||
insert_edge(graph, make_edge(uB, d_uB_v0))
|
||||
insert_edge(graph, make_edge(uA, d_uA_v0))
|
||||
insert_edge(graph, make_edge(uBp, d_uBp_v1))
|
||||
insert_edge(graph, make_edge(uAp, d_uAp_v1))
|
||||
insert_edge!(graph, make_edge(uB, d_uB_v0))
|
||||
insert_edge!(graph, make_edge(uA, d_uA_v0))
|
||||
insert_edge!(graph, make_edge(uBp, d_uBp_v1))
|
||||
insert_edge!(graph, make_edge(uAp, d_uAp_v1))
|
||||
|
||||
insert_edge(graph, make_edge(d_uB_v0, v0))
|
||||
insert_edge(graph, make_edge(d_uA_v0, v0))
|
||||
insert_edge(graph, make_edge(d_uBp_v1, v1))
|
||||
insert_edge(graph, make_edge(d_uAp_v1, v1))
|
||||
insert_edge!(graph, make_edge(d_uB_v0, v0))
|
||||
insert_edge!(graph, make_edge(d_uA_v0, v0))
|
||||
insert_edge!(graph, make_edge(d_uBp_v1, v1))
|
||||
insert_edge!(graph, make_edge(d_uAp_v1, v1))
|
||||
|
||||
insert_edge(graph, make_edge(v0, d_v0_s0))
|
||||
insert_edge(graph, make_edge(v1, d_v1_s0))
|
||||
insert_edge!(graph, make_edge(v0, d_v0_s0))
|
||||
insert_edge!(graph, make_edge(v1, d_v1_s0))
|
||||
|
||||
insert_edge(graph, make_edge(d_v0_s0, s0))
|
||||
insert_edge(graph, make_edge(d_v1_s0, s0))
|
||||
insert_edge!(graph, make_edge(d_v0_s0, s0))
|
||||
insert_edge!(graph, make_edge(d_v1_s0, s0))
|
||||
|
||||
insert_edge(graph, make_edge(s0, d_exit))
|
||||
insert_edge!(graph, make_edge(s0, d_exit))
|
||||
|
||||
print(graph)
|
||||
|
||||
@ -87,10 +87,10 @@ function main()
|
||||
println(generate_options(graph))
|
||||
|
||||
# fuse some things
|
||||
fuse1 = node_fusion(graph, PB, d_PB_uB, uB)
|
||||
fuse2 = node_fusion(graph, PA, d_PA_uA, uA)
|
||||
fuse3 = node_fusion(graph, PBp, d_PBp_uBp, uBp)
|
||||
fuse4 = node_fusion(graph, PAp, d_PAp_uAp, uAp)
|
||||
fuse1 = node_fusion!(graph, PB, d_PB_uB, uB)
|
||||
fuse2 = node_fusion!(graph, PA, d_PA_uA, uA)
|
||||
fuse3 = node_fusion!(graph, PBp, d_PBp_uBp, uBp)
|
||||
fuse4 = node_fusion!(graph, PAp, d_PAp_uAp, uAp)
|
||||
|
||||
# on this graph, nothing can be reduced
|
||||
println("Same graph after node fusion")
|
||||
|
@ -16,7 +16,7 @@ include("utility.jl")
|
||||
export Node, Edge, ComputeTaskNode, DataTaskNode, DAG
|
||||
export AbstractTask, AbstractComputeTask, AbstractDataTask, DataTask, ComputeTaskP, ComputeTaskS1, ComputeTaskS2, ComputeTaskV, ComputeTaskU, ComputeTaskSum, FusedComputeTask
|
||||
export make_node, make_edge, insert_node, insert_edge, is_entry_node, is_exit_node, parents, children, compute, graph_properties, get_exit_node, is_valid
|
||||
export node_fusion, node_reduction, node_split, generate_options
|
||||
export NodeFusion, NodeReduction, NodeSplit, push_operation!, pop_operation!, generate_options
|
||||
export import_txt
|
||||
|
||||
export ==, in, show
|
||||
|
83
src/graph.jl
83
src/graph.jl
@ -1,7 +1,88 @@
|
||||
using DataStructures
|
||||
|
||||
const Diff = NamedTuple{
|
||||
(:addedNodes, :removedNodes, :addedEdges, :removedEdges),
|
||||
Tuple{Vector{Node}, Vector{Node}, Vector{Edge}, Vector{Edge}}
|
||||
}
|
||||
|
||||
function Diff()
|
||||
return (
|
||||
addedNodes = Vector{Node}(),
|
||||
removedNodes = Vector{Node}(),
|
||||
addedEdges = Vector{Edge}(),
|
||||
removedEdges = Vector{Edge}()
|
||||
)::Diff
|
||||
end
|
||||
|
||||
# An abstract base class for operations
|
||||
# an operation can be applied to a DAG
|
||||
abstract type Operation end
|
||||
|
||||
# An abstract base class for already applied operations
|
||||
# an applied operation can be reversed iff it is the last applied operation on the DAG
|
||||
abstract type AppliedOperation end
|
||||
|
||||
struct NodeFusion <: Operation
|
||||
input::Tuple{ComputeTaskNode,DataTaskNode,ComputeTaskNode}
|
||||
end
|
||||
|
||||
struct AppliedNodeFusion <: AppliedOperation
|
||||
operation::NodeFusion
|
||||
diff::Diff
|
||||
end
|
||||
|
||||
struct NodeReduction <: Operation
|
||||
input::Vector{Node}
|
||||
end
|
||||
|
||||
struct AppliedNodeReduction <: AppliedOperation
|
||||
operation::NodeReduction
|
||||
diff::Diff
|
||||
end
|
||||
|
||||
struct NodeSplit <: Operation
|
||||
input::Node
|
||||
end
|
||||
|
||||
struct AppliedNodeSplit <: AppliedOperation
|
||||
operation::NodeSplit
|
||||
diff::Diff
|
||||
end
|
||||
|
||||
|
||||
const PossibleOperations = NamedTuple{
|
||||
(:nodeFusions, :nodeReductions, :nodeSplits),
|
||||
Tuple{Vector{NodeFusion}, Vector{NodeReduction}, Vector{NodeSplit}}
|
||||
}
|
||||
|
||||
function PossibleOperations()
|
||||
return (
|
||||
nodeFusions = Vector{NodeFusion}(),
|
||||
nodeReductions = Vector{NodeReduction}(),
|
||||
nodeSplits = Vector{NodeSplit}()
|
||||
)::PossibleOperations
|
||||
end
|
||||
|
||||
|
||||
# The actual state of the DAG is the initial state given by the set of nodes
|
||||
# but with all the operations in appliedChain applied in order
|
||||
mutable struct DAG
|
||||
nodes::Set{Node}
|
||||
|
||||
# The operations currently applied to the set of nodes
|
||||
appliedOperations::Stack{AppliedOperation}
|
||||
|
||||
# The operations not currently applied but part of the current state of the DAG
|
||||
operationsToApply::Deque{Operation}
|
||||
|
||||
# The possible operations at the current state of the DAG
|
||||
possibleOperations::PossibleOperations
|
||||
|
||||
# "snapshot" system: keep track of added/removed nodes/edges since last snapshot
|
||||
# these are muted in insert_node! etc.
|
||||
diff::Diff
|
||||
end
|
||||
|
||||
function DAG()
|
||||
return DAG(Set{Node}())
|
||||
return DAG(Set{Node}(), Stack{AppliedOperation}(), Deque{Operation}(), PossibleOperations(), Diff())
|
||||
end
|
||||
|
@ -63,43 +63,62 @@ end
|
||||
is_entry_node(node::Node) = length(children(node)) == 0
|
||||
is_exit_node(node::Node) = length(parents(node)) == 0
|
||||
|
||||
function insert_node(graph::DAG, node::Node)
|
||||
function insert_node!(graph::DAG, node::Node, track=true)
|
||||
push!(graph.nodes, node)
|
||||
|
||||
if (track) push!(graph.diff.addedNodes, node) end
|
||||
return node
|
||||
end
|
||||
|
||||
function insert_edge(graph::DAG, edge::Edge)
|
||||
function insert_edge!(graph::DAG, edge::Edge, track=true)
|
||||
# edge points from child to parent
|
||||
push!(edge.edge[1].parents, edge.edge[2])
|
||||
push!(edge.edge[2].children, edge.edge[1])
|
||||
|
||||
if (track) push!(graph.diff.addedEdges) end
|
||||
return edge
|
||||
end
|
||||
|
||||
function remove_node(graph::DAG, node::Node)
|
||||
function remove_node!(graph::DAG, node::Node, track=true)
|
||||
delete!(graph.nodes, node)
|
||||
|
||||
if (track) push!(graph.diff.removedNodes, node) end
|
||||
return nothing
|
||||
end
|
||||
|
||||
function remove_edge(graph::DAG, edge::Edge)
|
||||
function remove_edge!(graph::DAG, edge::Edge, track=true)
|
||||
filter!(x -> x != edge.edge[2], edge.edge[1].parents)
|
||||
filter!(x -> x != edge.edge[1], edge.edge[2].children)
|
||||
|
||||
if (track) push!(graph.diff.removedEdges, edge) end
|
||||
return nothing
|
||||
end
|
||||
|
||||
# return the graph "difference" since last time this function was called
|
||||
function get_snapshot_diff(graph::DAG)
|
||||
return swapfield!(graph, :diff, Diff())
|
||||
return result
|
||||
end
|
||||
|
||||
function graph_properties(graph::DAG)
|
||||
# make sure the graph is fully generated
|
||||
apply_all!(graph)
|
||||
|
||||
d = 0
|
||||
ce = 0
|
||||
ed = 0
|
||||
for node in graph.nodes
|
||||
d += data(node.task)
|
||||
ce += compute_effort(node.task)
|
||||
ed += length(node.parents)
|
||||
end
|
||||
|
||||
ci = ce / d
|
||||
|
||||
result = (data = d,
|
||||
compute_effort = ce,
|
||||
compute_intensity = ci)
|
||||
compute_intensity = ci,
|
||||
edges = ed)
|
||||
return result
|
||||
end
|
||||
|
||||
|
@ -1,5 +1,116 @@
|
||||
# Fuse nodes n1 -> n2 -> n3 together into one node, return the resulting new node
|
||||
function node_fusion(graph::DAG, n1::ComputeTaskNode, n2::DataTaskNode, n3::ComputeTaskNode)
|
||||
# outside interface
|
||||
|
||||
# applies a new operation to the end of the graph
|
||||
function push_operation!(graph::DAG, operation::Operation)
|
||||
# 1.: Add the operation to the DAG
|
||||
push!(graph.operationsToApply, operation)
|
||||
|
||||
# 2.: Apply all operations in the chain
|
||||
apply_all!(graph)
|
||||
|
||||
# 3.: Regenerate properties, possible operations from here
|
||||
|
||||
end
|
||||
|
||||
# reverts the latest applied operation, essentially like a ctrl+z for
|
||||
function pop_operation!(graph::DAG)
|
||||
# 1.: Remove the operation from the appliedChain of the DAG
|
||||
if !isempty(graph.operationsToApply)
|
||||
pop!(graph.operationsToApply)
|
||||
elseif !isempty(graph.appliedOperations)
|
||||
appliedOp = pop!(graph.appliedOperations)
|
||||
revert_operation!(graph, appliedOp)
|
||||
else
|
||||
error("No more operations to pop!")
|
||||
end
|
||||
|
||||
# 2.: Apply all (remaining) operations in the chain
|
||||
apply_all!(graph)
|
||||
|
||||
# 3.: Regenerate properties, possible operations from here
|
||||
|
||||
end
|
||||
|
||||
# implementation detail functions, don't export
|
||||
|
||||
# applies all unapplied operations in the DAG
|
||||
function apply_all!(graph::DAG)
|
||||
while !isempty(graph.operationsToApply)
|
||||
# get next operation to apply from front of the deque
|
||||
op = popfirst!(graph.operationsToApply)
|
||||
|
||||
# apply it
|
||||
appliedOp = apply_operation!(graph, op)
|
||||
|
||||
# push to the end of the appliedOperations deque
|
||||
push!(graph.appliedOperations, appliedOp)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function apply_operation!(graph::DAG, operation::Operation)
|
||||
error("Unknown operation type!")
|
||||
end
|
||||
|
||||
function apply_operation!(graph::DAG, operation::NodeFusion)
|
||||
diff = node_fusion!(graph, operation.input[1], operation.input[2], operation.input[3])
|
||||
return AppliedNodeFusion(operation, diff)
|
||||
end
|
||||
|
||||
function apply_operation!(graph::DAG, operation::NodeReduction)
|
||||
diff = node_reduction!(graph, operation.input[1], operation.input[2])
|
||||
return AppliedNodeReduction(operation, diff)
|
||||
end
|
||||
|
||||
function apply_operation!(graph::DAG, operation::NodeSplit)
|
||||
diff = node_split!(graph, operation.input[1])
|
||||
return AppliedNodeSplit(operation, diff)
|
||||
end
|
||||
|
||||
|
||||
function revert_operation!(graph::DAG, operation::AppliedOperation)
|
||||
error("Unknown operation type!")
|
||||
end
|
||||
|
||||
function revert_operation!(graph::DAG, operation::AppliedNodeFusion)
|
||||
revert_diff!(graph, operation.diff)
|
||||
return operation.operation
|
||||
end
|
||||
|
||||
function revert_operation!(graph::DAG, operation::AppliedNodeReduction)
|
||||
revert_diff!(graph, operation.diff)
|
||||
return operation.operation
|
||||
end
|
||||
|
||||
function revert_operation!(graph::DAG, operation::AppliedNodeSplit)
|
||||
revert_diff!(graph, operation.diff)
|
||||
return operation.operation
|
||||
end
|
||||
|
||||
|
||||
function revert_diff!(graph::DAG, diff)
|
||||
# add removed nodes, remove added nodes, same for edges
|
||||
# note the order
|
||||
for edge in diff.addedEdges
|
||||
remove_edge!(graph, edge, false)
|
||||
end
|
||||
for node in diff.addedNodes
|
||||
remove_node!(graph, node, false)
|
||||
end
|
||||
|
||||
for node in diff.removedNodes
|
||||
insert_node!(graph, node, false)
|
||||
end
|
||||
for edge in diff.removedEdges
|
||||
insert_edge!(graph, edge, false)
|
||||
end
|
||||
end
|
||||
|
||||
# Fuse nodes n1 -> n2 -> n3 together into one node, return the applied difference to the graph
|
||||
function node_fusion!(graph::DAG, n1::ComputeTaskNode, n2::DataTaskNode, n3::ComputeTaskNode)
|
||||
# clear snapshot
|
||||
get_snapshot_diff(graph)
|
||||
|
||||
if !(n1 in graph) || !(n2 in graph) || !(n3 in graph)
|
||||
error("[Node Fusion] The given nodes are not part of the given graph")
|
||||
end
|
||||
@ -22,41 +133,44 @@ function node_fusion(graph::DAG, n1::ComputeTaskNode, n2::DataTaskNode, n3::Comp
|
||||
required_edge2 = make_edge(n2, n3)
|
||||
|
||||
# remove the edges and nodes that will be replaced by the fused node
|
||||
remove_edge(graph, required_edge1)
|
||||
remove_edge(graph, required_edge2)
|
||||
remove_node(graph, n1)
|
||||
remove_node(graph, n2)
|
||||
remove_edge!(graph, required_edge1)
|
||||
remove_edge!(graph, required_edge2)
|
||||
remove_node!(graph, n1)
|
||||
remove_node!(graph, n2)
|
||||
|
||||
# get n3's children now so it automatically excludes n2
|
||||
n3_children = children(n3)
|
||||
remove_node(graph, n3)
|
||||
remove_node!(graph, n3)
|
||||
|
||||
# create new node with the fused compute task
|
||||
new_node = ComputeTaskNode(FusedComputeTask{typeof(n1.task), typeof(n3.task)}())
|
||||
insert_node(graph, new_node)
|
||||
insert_node!(graph, new_node)
|
||||
|
||||
# "repoint" children of n1 to the new node
|
||||
for child in n1_children
|
||||
remove_edge(graph, make_edge(child, n1))
|
||||
insert_edge(graph, make_edge(child, new_node))
|
||||
remove_edge!(graph, make_edge(child, n1))
|
||||
insert_edge!(graph, make_edge(child, new_node))
|
||||
end
|
||||
|
||||
# "repoint" children of n3 to the new node
|
||||
for child in n3_children
|
||||
remove_edge(graph, make_edge(child, n3))
|
||||
insert_edge(graph, make_edge(child, new_node))
|
||||
remove_edge!(graph, make_edge(child, n3))
|
||||
insert_edge!(graph, make_edge(child, new_node))
|
||||
end
|
||||
|
||||
# "repoint" parents of n3 from new node
|
||||
for parent in n3_parents
|
||||
remove_edge(graph, make_edge(n3, parent))
|
||||
insert_edge(graph, make_edge(new_node, parent))
|
||||
remove_edge!(graph, make_edge(n3, parent))
|
||||
insert_edge!(graph, make_edge(new_node, parent))
|
||||
end
|
||||
|
||||
return new_node
|
||||
return get_snapshot_diff(graph)
|
||||
end
|
||||
|
||||
function node_reduction(graph::DAG, n1::Node, n2::Node)
|
||||
function node_reduction!(graph::DAG, n1::Node, n2::Node)
|
||||
# clear snapshot
|
||||
get_snapshot_diff(graph)
|
||||
|
||||
if !(n1 in graph) || !(n2 in graph)
|
||||
error("[Node Reduction] The given nodes are not part of the given graph")
|
||||
end
|
||||
@ -75,20 +189,23 @@ function node_reduction(graph::DAG, n1::Node, n2::Node)
|
||||
|
||||
# remove n2 and all its parents and children
|
||||
for child in n2_children
|
||||
remove_edge(graph, make_edge(child, n2))
|
||||
remove_edge!(graph, make_edge(child, n2))
|
||||
end
|
||||
for parent in n2_parents
|
||||
remove_edge(graph, make_edge(n2, parent))
|
||||
remove_edge!(graph, make_edge(n2, parent))
|
||||
|
||||
# add parents of n2 to n1
|
||||
insert_edge(graph, make_edge(n1, parent))
|
||||
insert_edge!(graph, make_edge(n1, parent))
|
||||
end
|
||||
remove_node(graph, n2)
|
||||
remove_node!(graph, n2)
|
||||
|
||||
return n1
|
||||
return get_snapshot_diff(graph)
|
||||
end
|
||||
|
||||
function node_split(graph::DAG, n1::Node)
|
||||
function node_split!(graph::DAG, n1::Node)
|
||||
# clear snapshot
|
||||
get_snapshot_diff(graph)
|
||||
|
||||
if !(n1 in graph)
|
||||
error("[Node Split] The given node is not part of the given graph")
|
||||
end
|
||||
@ -102,23 +219,24 @@ function node_split(graph::DAG, n1::Node)
|
||||
|
||||
for parent in n1_parents
|
||||
n_copy = copy(n1)
|
||||
insert_node(graph, n_copy)
|
||||
insert_edge(graph, make_edge(n_copy, parent))
|
||||
remove_edge(graph, make_edge(n1, parent))
|
||||
insert_node!(graph, n_copy)
|
||||
insert_edge!(graph, make_edge(n_copy, parent))
|
||||
remove_edge!(graph, make_edge(n1, parent))
|
||||
|
||||
for child in n1_children
|
||||
insert_edge(graph, make_edge(child, n_copy))
|
||||
insert_edge!(graph, make_edge(child, n_copy))
|
||||
end
|
||||
end
|
||||
|
||||
return nothing
|
||||
return get_snapshot_diff(graph)
|
||||
end
|
||||
|
||||
# function to generate all possible optmizations on the graph
|
||||
function generate_options(graph::DAG)
|
||||
options = (fusions = Vector{Tuple{ComputeTaskNode, DataTaskNode, ComputeTaskNode}}(),
|
||||
reductions = Vector{Vector{Node}}(),
|
||||
splits = Vector{Node}())
|
||||
options = PossibleOperations()
|
||||
|
||||
# make sure the graph is fully generated through
|
||||
apply_all!(graph)
|
||||
|
||||
# find possible node fusions
|
||||
for node in graph.nodes
|
||||
@ -137,7 +255,7 @@ function generate_options(graph::DAG)
|
||||
end
|
||||
child_node = pop!(node_children)
|
||||
|
||||
push!(options.fusions, (child_node, node, parent_node))
|
||||
push!(options.nodeFusions, NodeFusion((child_node, node, parent_node)))
|
||||
end
|
||||
end
|
||||
|
||||
@ -159,7 +277,7 @@ function generate_options(graph::DAG)
|
||||
# only when there's at least one reduction partner, insert the vector
|
||||
reductionVector = Vector{Node}
|
||||
push!(reductionVector, node)
|
||||
push!(options.reductions, reductionVector)
|
||||
push!(options.nodeReductions, NodeReduction(reductionVector))
|
||||
end
|
||||
|
||||
push!(reductionVector, partner)
|
||||
@ -171,7 +289,7 @@ function generate_options(graph::DAG)
|
||||
# find possible node splits
|
||||
for node in graph.nodes
|
||||
if (can_split(node))
|
||||
push!(options.splits, node)
|
||||
push!(options.nodeSplits, NodeSplit(node))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -39,9 +39,9 @@ function import_txt(filename::String, verbose::Bool = isinteractive())
|
||||
if (verbose) println("Estimating ", estimate_no_nodes, " Nodes") end
|
||||
sizehint!(graph.nodes, estimate_no_nodes)
|
||||
|
||||
sum_node = insert_node(graph, make_node(ComputeTaskSum()))
|
||||
global_data_out = insert_node(graph, make_node(DataTask(10)))
|
||||
insert_edge(graph, make_edge(sum_node, global_data_out))
|
||||
sum_node = insert_node!(graph, make_node(ComputeTaskSum()), false)
|
||||
global_data_out = insert_node!(graph, make_node(DataTask(10)), false)
|
||||
insert_edge!(graph, make_edge(sum_node, global_data_out), false)
|
||||
|
||||
# remember the data out nodes for connection
|
||||
dataOutNodes = Dict()
|
||||
@ -57,16 +57,16 @@ function import_txt(filename::String, verbose::Bool = isinteractive())
|
||||
end
|
||||
if occursin(regex_a, node)
|
||||
# add nodes and edges for the state reading to u(P(Particle))
|
||||
data_in = insert_node(graph, make_node(DataTask(4))) # read particle data node
|
||||
compute_P = insert_node(graph, make_node(ComputeTaskP())) # compute P node
|
||||
data_Pu = insert_node(graph, make_node(DataTask(6))) # transfer data from P to u
|
||||
compute_u = insert_node(graph, make_node(ComputeTaskU())) # compute U node
|
||||
data_out = insert_node(graph, make_node(DataTask(3))) # transfer data out from u
|
||||
data_in = insert_node!(graph, make_node(DataTask(4)), false) # read particle data node
|
||||
compute_P = insert_node!(graph, make_node(ComputeTaskP()), false) # compute P node
|
||||
data_Pu = insert_node!(graph, make_node(DataTask(6)), false) # transfer data from P to u
|
||||
compute_u = insert_node!(graph, make_node(ComputeTaskU()), false) # compute U node
|
||||
data_out = insert_node!(graph, make_node(DataTask(3)), false) # transfer data out from u
|
||||
|
||||
insert_edge(graph, make_edge(data_in, compute_P))
|
||||
insert_edge(graph, make_edge(compute_P, data_Pu))
|
||||
insert_edge(graph, make_edge(data_Pu, compute_u))
|
||||
insert_edge(graph, make_edge(compute_u, data_out))
|
||||
insert_edge!(graph, make_edge(data_in, compute_P), false)
|
||||
insert_edge!(graph, make_edge(compute_P, data_Pu), false)
|
||||
insert_edge!(graph, make_edge(data_Pu, compute_u), false)
|
||||
insert_edge!(graph, make_edge(compute_u, data_out), false)
|
||||
|
||||
# remember the data_out node for future edges
|
||||
dataOutNodes[node] = data_out
|
||||
@ -76,37 +76,37 @@ function import_txt(filename::String, verbose::Bool = isinteractive())
|
||||
in1 = capt.captures[1]
|
||||
in2 = capt.captures[2]
|
||||
|
||||
compute_v = insert_node(graph, make_node(ComputeTaskV()))
|
||||
data_out = insert_node(graph, make_node(DataTask(5)))
|
||||
compute_v = insert_node!(graph, make_node(ComputeTaskV()), false)
|
||||
data_out = insert_node!(graph, make_node(DataTask(5)), false)
|
||||
|
||||
if (occursin(regex_c, capt.captures[1]))
|
||||
# put an S node after this input
|
||||
compute_S = insert_node(graph, make_node(ComputeTaskS1()))
|
||||
data_S_v = insert_node(graph, make_node(DataTask(5)))
|
||||
compute_S = insert_node!(graph, make_node(ComputeTaskS1()), false)
|
||||
data_S_v = insert_node!(graph, make_node(DataTask(5)), false)
|
||||
|
||||
insert_edge(graph, make_edge(dataOutNodes[capt.captures[1]], compute_S))
|
||||
insert_edge(graph, make_edge(compute_S, data_S_v))
|
||||
insert_edge!(graph, make_edge(dataOutNodes[capt.captures[1]], compute_S), false)
|
||||
insert_edge!(graph, make_edge(compute_S, data_S_v), false)
|
||||
|
||||
insert_edge(graph, make_edge(data_S_v, compute_v))
|
||||
insert_edge!(graph, make_edge(data_S_v, compute_v), false)
|
||||
else
|
||||
insert_edge(graph, make_edge(dataOutNodes[capt.captures[1]], compute_v))
|
||||
insert_edge!(graph, make_edge(dataOutNodes[capt.captures[1]], compute_v), false)
|
||||
end
|
||||
|
||||
if (occursin(regex_c, capt.captures[2]))
|
||||
# i think the current generator only puts the combined particles in the first space, so this case might never be entered
|
||||
# put an S node after this input
|
||||
compute_S = insert_node(graph, make_node(ComputeTaskS1()))
|
||||
data_S_v = insert_node(graph, make_node(DataTask(5)))
|
||||
compute_S = insert_node!(graph, make_node(ComputeTaskS1()), false)
|
||||
data_S_v = insert_node!(graph, make_node(DataTask(5)), false)
|
||||
|
||||
insert_edge(graph, make_edge(dataOutNodes[capt.captures[2]], compute_S))
|
||||
insert_edge(graph, make_edge(compute_S, data_S_v))
|
||||
insert_edge!(graph, make_edge(dataOutNodes[capt.captures[2]], compute_S), false)
|
||||
insert_edge!(graph, make_edge(compute_S, data_S_v), false)
|
||||
|
||||
insert_edge(graph, make_edge(data_S_v, compute_v))
|
||||
insert_edge!(graph, make_edge(data_S_v, compute_v), false)
|
||||
else
|
||||
insert_edge(graph, make_edge(dataOutNodes[capt.captures[2]], compute_v))
|
||||
insert_edge!(graph, make_edge(dataOutNodes[capt.captures[2]], compute_v), false)
|
||||
end
|
||||
|
||||
insert_edge(graph, make_edge(compute_v, data_out))
|
||||
insert_edge!(graph, make_edge(compute_v, data_out), false)
|
||||
dataOutNodes[node] = data_out
|
||||
|
||||
elseif occursin(regex_m, node)
|
||||
@ -117,22 +117,22 @@ function import_txt(filename::String, verbose::Bool = isinteractive())
|
||||
in3 = capt.captures[3]
|
||||
|
||||
# in2 + in3 with a v
|
||||
compute_v = insert_node(graph, make_node(ComputeTaskV()))
|
||||
data_v = insert_node(graph, make_node(DataTask(5)))
|
||||
compute_v = insert_node!(graph, make_node(ComputeTaskV()), false)
|
||||
data_v = insert_node!(graph, make_node(DataTask(5)), false)
|
||||
|
||||
insert_edge(graph, make_edge(dataOutNodes[in2], compute_v))
|
||||
insert_edge(graph, make_edge(dataOutNodes[in3], compute_v))
|
||||
insert_edge(graph, make_edge(compute_v, data_v))
|
||||
insert_edge!(graph, make_edge(dataOutNodes[in2], compute_v), false)
|
||||
insert_edge!(graph, make_edge(dataOutNodes[in3], compute_v), false)
|
||||
insert_edge!(graph, make_edge(compute_v, data_v), false)
|
||||
|
||||
# combine with the v of the combined other input
|
||||
compute_S2 = insert_node(graph, make_node(ComputeTaskS2()))
|
||||
data_out = insert_node(graph, make_node(DataTask(10)))
|
||||
compute_S2 = insert_node!(graph, make_node(ComputeTaskS2()), false)
|
||||
data_out = insert_node!(graph, make_node(DataTask(10)), false)
|
||||
|
||||
insert_edge(graph, make_edge(data_v, compute_S2))
|
||||
insert_edge(graph, make_edge(dataOutNodes[in1], compute_S2))
|
||||
insert_edge(graph, make_edge(compute_S2, data_out))
|
||||
insert_edge!(graph, make_edge(data_v, compute_S2), false)
|
||||
insert_edge!(graph, make_edge(dataOutNodes[in1], compute_S2), false)
|
||||
insert_edge!(graph, make_edge(compute_S2, data_out), false)
|
||||
|
||||
insert_edge(graph, make_edge(data_out, sum_node))
|
||||
insert_edge!(graph, make_edge(data_out, sum_node), false)
|
||||
elseif occursin(regex_plus, node)
|
||||
if (verbose)
|
||||
println("\rReading Nodes Complete ")
|
||||
|
@ -9,7 +9,7 @@ function test_known_graphs()
|
||||
@test props.compute_effort == 185
|
||||
@test props.data == 102
|
||||
|
||||
@test length(generate_options(g_ABAB).fusions) == 10
|
||||
@test length(generate_options(g_ABAB).nodeFusions) == 10
|
||||
|
||||
test_node_fusion(g_ABAB)
|
||||
|
||||
@ -33,11 +33,12 @@ function test_node_fusion(g)
|
||||
data = props.data
|
||||
compute_effort = props.compute_effort
|
||||
|
||||
while length(options.fusions) != 0
|
||||
fusion = options.fusions[1]
|
||||
n = node_fusion(g, fusion[1], fusion[2], fusion[3])
|
||||
@test typeof(n.task) <: FusedComputeTask
|
||||
@test length(g.nodes) == nodes_number - 2
|
||||
while !isempty(options.nodeFusions)
|
||||
fusion = options.nodeFusions[1]
|
||||
|
||||
@test typeof(fusion) <: NodeFusion
|
||||
|
||||
push_operation!(g, fusion)
|
||||
|
||||
props = graph_properties(g)
|
||||
@test props.data < data
|
||||
|
Loading…
x
Reference in New Issue
Block a user