Work on optimization functions
This commit is contained in:
parent
190a4252f8
commit
5bf660618d
@ -4,76 +4,48 @@ function main()
|
||||
graph = DAG()
|
||||
|
||||
# s to output (exit node)
|
||||
d_exit = make_node(DataTask(10))
|
||||
d_exit = insert_node(graph, make_node(DataTask(10)))
|
||||
|
||||
# final s compute
|
||||
s0 = make_node(ComputeTaskS2())
|
||||
s0 = insert_node(graph, make_node(ComputeTaskS2()))
|
||||
|
||||
# data from v0 and v1 to s0
|
||||
d_v0_s0 = make_node(DataTask(5))
|
||||
d_v1_s0 = 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 = make_node(ComputeTaskV())
|
||||
v1 = 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 = make_node(DataTask(3))
|
||||
d_uA_v0 = make_node(DataTask(3))
|
||||
d_uBp_v1 = make_node(DataTask(3))
|
||||
d_uAp_v1 = 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 = make_node(ComputeTaskU())
|
||||
uA = make_node(ComputeTaskU())
|
||||
uBp = make_node(ComputeTaskU())
|
||||
uAp = 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 = make_node(DataTask(6))
|
||||
d_PA_uA = make_node(DataTask(6))
|
||||
d_PBp_uBp = make_node(DataTask(6))
|
||||
d_PAp_uAp = 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 = make_node(ComputeTaskP())
|
||||
PA = make_node(ComputeTaskP())
|
||||
PBp = make_node(ComputeTaskP())
|
||||
PAp = 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 = make_node(DataTask(4))
|
||||
d_PA = make_node(DataTask(4))
|
||||
d_PBp = make_node(DataTask(4))
|
||||
d_PAp = make_node(DataTask(4))
|
||||
|
||||
# now insert them all
|
||||
insert_node(graph, d_exit)
|
||||
insert_node(graph, s0)
|
||||
insert_node(graph, d_v0_s0)
|
||||
insert_node(graph, d_v1_s0)
|
||||
insert_node(graph, v0)
|
||||
insert_node(graph, v1)
|
||||
insert_node(graph, d_uB_v0)
|
||||
insert_node(graph, d_uA_v0)
|
||||
insert_node(graph, d_uBp_v1)
|
||||
insert_node(graph, d_uAp_v1)
|
||||
insert_node(graph, uB)
|
||||
insert_node(graph, uA)
|
||||
insert_node(graph, uBp)
|
||||
insert_node(graph, uAp)
|
||||
insert_node(graph, d_PB_uB)
|
||||
insert_node(graph, d_PA_uA)
|
||||
insert_node(graph, d_PBp_uBp)
|
||||
insert_node(graph, d_PAp_uAp)
|
||||
insert_node(graph, PB)
|
||||
insert_node(graph, PA)
|
||||
insert_node(graph, PBp)
|
||||
insert_node(graph, PAp)
|
||||
insert_node(graph, d_PB)
|
||||
insert_node(graph, d_PA)
|
||||
insert_node(graph, d_PBp)
|
||||
insert_node(graph, d_PAp)
|
||||
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))
|
||||
@ -111,6 +83,9 @@ function main()
|
||||
|
||||
print(graph)
|
||||
|
||||
println("Available optimizations from here:")
|
||||
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)
|
||||
@ -118,9 +93,11 @@ function main()
|
||||
fuse4 = node_fusion(graph, PAp, d_PAp_uAp, uAp)
|
||||
|
||||
# on this graph, nothing can be reduced
|
||||
|
||||
println("Same graph after node fusion")
|
||||
print(graph)
|
||||
|
||||
println("Available optimizations from here:")
|
||||
println(generate_options(graph))
|
||||
end
|
||||
|
||||
main()
|
||||
|
@ -49,12 +49,12 @@ is_exit_node(graph::DAG, node::Node) = size(parents(graph, node)) == 0
|
||||
|
||||
function insert_node(graph::DAG, node::Node)
|
||||
push!(graph.nodes, node)
|
||||
return nothing
|
||||
return node
|
||||
end
|
||||
|
||||
function insert_edge(graph::DAG, edge::Edge)
|
||||
push!(graph.edges, edge)
|
||||
return nothing
|
||||
return edge
|
||||
end
|
||||
|
||||
function remove_node(graph::DAG, node::Node)
|
||||
@ -91,6 +91,15 @@ function compute_intensity(graph::DAG)
|
||||
return compute_effort(graph) / data_sum
|
||||
end
|
||||
|
||||
function get_exit_node(graph::DAG)
|
||||
for node in graph.nodes
|
||||
if (is_exit_node(graph, node))
|
||||
return node
|
||||
end
|
||||
end
|
||||
error("The given graph has no exit node! It is either empty or not acyclic!")
|
||||
end
|
||||
|
||||
function show_nodes(io, graph::DAG)
|
||||
print(io, "[")
|
||||
first = true
|
||||
@ -98,7 +107,7 @@ function show_nodes(io, graph::DAG)
|
||||
if first
|
||||
first = false
|
||||
else
|
||||
print(", ")
|
||||
print(io, ", ")
|
||||
end
|
||||
print(io, n)
|
||||
end
|
||||
@ -112,7 +121,7 @@ function show_edges(io, graph::DAG)
|
||||
if first
|
||||
first = false
|
||||
else
|
||||
print(", ")
|
||||
print(io, ", ")
|
||||
end
|
||||
print(io, e)
|
||||
end
|
||||
@ -121,13 +130,13 @@ end
|
||||
|
||||
function show(io::IO, graph::DAG)
|
||||
println(io, "Graph:")
|
||||
print(" Nodes: ")
|
||||
print(io, " Nodes: ")
|
||||
show_nodes(io, graph)
|
||||
println()
|
||||
print(" Edges: ")
|
||||
println(io)
|
||||
print(io, " Edges: ")
|
||||
show_edges(io, graph)
|
||||
println()
|
||||
println(" Total Compute Effort: ", compute_effort(graph))
|
||||
println(" Total Data Transfer: ", data(graph))
|
||||
println(" Total Compute Intensity: ", compute_intensity(graph))
|
||||
println(io)
|
||||
println(io, " Total Compute Effort: ", compute_effort(graph))
|
||||
println(io, " Total Data Transfer: ", data(graph))
|
||||
println(io, " Total Compute Intensity: ", compute_intensity(graph))
|
||||
end
|
||||
|
@ -13,24 +13,42 @@ function node_fusion(graph::DAG, n1::ComputeTaskNode, n2::DataTaskNode, n3::Comp
|
||||
|
||||
# save children and parents
|
||||
n1_children = children(graph, n1)
|
||||
n2_parents = parents(graph, n2)
|
||||
n3_parents = parents(graph, n3)
|
||||
|
||||
if length(n2_parents) > 1
|
||||
error("[Node Fusion] The given data node has more than one parent")
|
||||
end
|
||||
|
||||
# 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)
|
||||
|
||||
# get n3's children now so it automatically excludes n2
|
||||
n3_children = children(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)
|
||||
|
||||
# "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))
|
||||
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))
|
||||
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))
|
||||
end
|
||||
|
||||
@ -66,7 +84,7 @@ function node_reduction(graph::DAG, n1::Node, n2::Node)
|
||||
end
|
||||
remove_node(graph, n2)
|
||||
|
||||
return nothing
|
||||
return n1
|
||||
end
|
||||
|
||||
function node_split(graph::DAG, n1::Node)
|
||||
@ -77,7 +95,7 @@ function node_split(graph::DAG, n1::Node)
|
||||
n1_parents = parents(graph, n1)
|
||||
n1_children = children(graph, n1)
|
||||
|
||||
if size(n1_parents) <= 1
|
||||
if length(n1_parents) <= 1
|
||||
error("[Node Split] The given node does not have multiple parents which is required for node split")
|
||||
end
|
||||
|
||||
@ -94,3 +112,39 @@ function node_split(graph::DAG, n1::Node)
|
||||
|
||||
return nothing
|
||||
end
|
||||
|
||||
# function to generate all possible optmizations on the graph
|
||||
function generate_options(graph::DAG)
|
||||
options = (fusions = Vector{Tuple{ComputeTaskNode, DataTaskNode, ComputeTaskNode}}(),
|
||||
reductions = Vector{Tuple{Node, Node}}(),
|
||||
splits = Vector{Tuple{Node}}())
|
||||
|
||||
# find possible node fusions
|
||||
for node in graph.nodes
|
||||
if (typeof(node) <: DataTaskNode)
|
||||
node_parents = parents(graph, node)
|
||||
if length(node_parents) != 1
|
||||
# data node can only have a single parent
|
||||
continue
|
||||
end
|
||||
parent_node = node_parents[1]
|
||||
|
||||
node_children = children(graph, node)
|
||||
if length(node_children) != 1
|
||||
# this node is an entry node or has multiple children which should not be possible
|
||||
continue
|
||||
end
|
||||
child_node = node_children[1]
|
||||
|
||||
push!(options.fusions, (child_node, node, parent_node))
|
||||
end
|
||||
end
|
||||
|
||||
# find possible node reductions
|
||||
|
||||
|
||||
# find possible node splits
|
||||
|
||||
|
||||
return options
|
||||
end
|
||||
|
@ -13,8 +13,8 @@ include("graph_optimizations.jl")
|
||||
|
||||
export Node, Edge, ComputeTaskNode, DataTaskNode, DAG
|
||||
export AbstractTask, AbstractComputeTask, AbstractDataTask, DataTask, ComputeTaskP, ComputeTaskS1, ComputeTaskS2, ComputeTaskV, ComputeTaskU, FusedComputeTask
|
||||
export make_node, make_edge, insert_node, insert_edge, is_entry_node, is_exit_node, parents, children, compute, data, compute_effort, compute_intensity
|
||||
export node_fusion, node_reduction, node_split
|
||||
export make_node, make_edge, insert_node, insert_edge, is_entry_node, is_exit_node, parents, children, compute, data, compute_effort, compute_intensity, get_exit_node
|
||||
export node_fusion, node_reduction, node_split, generate_options
|
||||
|
||||
export ==, in, show
|
||||
|
||||
|
@ -50,7 +50,7 @@ show(io::IO, t::ComputeTaskU) = print("ComputeU")
|
||||
show(io::IO, t::ComputeTaskV) = print("ComputeV")
|
||||
|
||||
function show(io::IO, t::FusedComputeTask)
|
||||
(T1, T2) = collect(typeof(t).parameters)
|
||||
(T1, T2) = get_types(t)
|
||||
print(io, "ComputeFuse(", T1(), ", ", T2(), ")")
|
||||
end
|
||||
|
||||
|
@ -29,3 +29,5 @@ end
|
||||
|
||||
struct FusedComputeTask{T1<:AbstractComputeTask, T2<:AbstractComputeTask} <: AbstractComputeTask
|
||||
end
|
||||
|
||||
get_types(::FusedComputeTask{T1, T2}) where {T1, T2} = (T1, T2)
|
||||
|
Loading…
x
Reference in New Issue
Block a user