2023-08-29 12:57:46 +02:00
|
|
|
# These are functions for "cleaning" nodes, i.e. regenerating the possible operations for a node
|
2023-08-21 12:54:45 +02:00
|
|
|
|
2023-08-29 12:57:46 +02:00
|
|
|
"""
|
|
|
|
find_fusions!(graph::DAG, node::DataTaskNode)
|
|
|
|
|
|
|
|
Find node fusions involving the given data node. The function pushes the found [`NodeFusion`](@ref) (if any) everywhere it needs to be and returns nothing.
|
|
|
|
|
|
|
|
Does nothing if the node already has a node fusion set. Since it's a data node, only one node fusion can be possible with it.
|
|
|
|
"""
|
2023-08-21 12:54:45 +02:00
|
|
|
function find_fusions!(graph::DAG, node::DataTaskNode)
|
2023-08-29 12:57:46 +02:00
|
|
|
# if there is already a fusion here, skip to avoid duplicates
|
2023-08-25 10:48:22 +02:00
|
|
|
if !ismissing(node.nodeFusion)
|
|
|
|
return nothing
|
|
|
|
end
|
2023-08-23 12:51:25 +02:00
|
|
|
|
2023-08-25 10:48:22 +02:00
|
|
|
if length(node.parents) != 1 || length(node.children) != 1
|
|
|
|
return nothing
|
|
|
|
end
|
2023-08-21 12:54:45 +02:00
|
|
|
|
2023-08-25 10:48:22 +02:00
|
|
|
child_node = first(node.children)
|
|
|
|
parent_node = first(node.parents)
|
2023-08-21 12:54:45 +02:00
|
|
|
|
2023-08-25 10:48:22 +02:00
|
|
|
if !(child_node in graph) || !(parent_node in graph)
|
|
|
|
error("Parents/Children that are not in the graph!!!")
|
|
|
|
end
|
2023-08-21 12:54:45 +02:00
|
|
|
|
2023-08-25 10:48:22 +02:00
|
|
|
if length(child_node.parents) != 1
|
|
|
|
return nothing
|
|
|
|
end
|
2023-08-21 12:54:45 +02:00
|
|
|
|
2023-08-25 10:48:22 +02:00
|
|
|
nf = NodeFusion((child_node, node, parent_node))
|
|
|
|
push!(graph.possibleOperations.nodeFusions, nf)
|
|
|
|
push!(child_node.nodeFusions, nf)
|
|
|
|
node.nodeFusion = nf
|
|
|
|
push!(parent_node.nodeFusions, nf)
|
2023-08-21 12:54:45 +02:00
|
|
|
|
2023-08-25 10:48:22 +02:00
|
|
|
return nothing
|
2023-08-21 12:54:45 +02:00
|
|
|
end
|
|
|
|
|
2023-08-29 12:57:46 +02:00
|
|
|
"""
|
|
|
|
find_fusions!(graph::DAG, node::ComputeTaskNode)
|
2023-08-21 12:54:45 +02:00
|
|
|
|
2023-08-29 12:57:46 +02:00
|
|
|
Find node fusions involving the given compute node. The function pushes the found [`NodeFusion`](@ref)s (if any) everywhere they need to be and returns nothing.
|
|
|
|
"""
|
2023-08-23 12:51:25 +02:00
|
|
|
function find_fusions!(graph::DAG, node::ComputeTaskNode)
|
2023-08-25 10:48:22 +02:00
|
|
|
# just find fusions in neighbouring DataTaskNodes
|
|
|
|
for child in node.children
|
|
|
|
find_fusions!(graph, child)
|
|
|
|
end
|
2023-08-21 12:54:45 +02:00
|
|
|
|
2023-08-25 10:48:22 +02:00
|
|
|
for parent in node.parents
|
|
|
|
find_fusions!(graph, parent)
|
|
|
|
end
|
2023-08-21 12:54:45 +02:00
|
|
|
|
2023-08-25 10:48:22 +02:00
|
|
|
return nothing
|
2023-08-21 12:54:45 +02:00
|
|
|
end
|
|
|
|
|
2023-08-29 12:57:46 +02:00
|
|
|
"""
|
|
|
|
find_reductions!(graph::DAG, node::Node)
|
|
|
|
|
|
|
|
Find node reductions involving the given node. The function pushes the found [`NodeReduction`](@ref) (if any) everywhere it needs to be and returns nothing.
|
|
|
|
"""
|
2023-08-21 12:54:45 +02:00
|
|
|
function find_reductions!(graph::DAG, node::Node)
|
2023-08-25 10:48:22 +02:00
|
|
|
# there can only be one reduction per node, avoid adding duplicates
|
|
|
|
if !ismissing(node.nodeReduction)
|
|
|
|
return nothing
|
|
|
|
end
|
|
|
|
|
|
|
|
reductionVector = nothing
|
|
|
|
# possible reductions are with nodes that are partners, i.e. parents of children
|
|
|
|
partners_ = partners(node)
|
|
|
|
delete!(partners_, node)
|
|
|
|
for partner in partners_
|
|
|
|
if partner ∉ graph.nodes
|
|
|
|
error("Partner is not part of the graph")
|
|
|
|
end
|
|
|
|
|
|
|
|
if can_reduce(node, partner)
|
|
|
|
if Set(node.children) != Set(partner.children)
|
|
|
|
error("Not equal children")
|
|
|
|
end
|
|
|
|
if reductionVector === nothing
|
|
|
|
# only when there's at least one reduction partner, insert the vector
|
|
|
|
reductionVector = Vector{Node}()
|
|
|
|
push!(reductionVector, node)
|
|
|
|
end
|
|
|
|
|
|
|
|
push!(reductionVector, partner)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if reductionVector !== nothing
|
|
|
|
nr = NodeReduction(reductionVector)
|
|
|
|
push!(graph.possibleOperations.nodeReductions, nr)
|
|
|
|
for node in reductionVector
|
|
|
|
if !ismissing(node.nodeReduction)
|
|
|
|
# it can happen that the dirty node becomes part of an existing NodeReduction and overrides those ones now
|
|
|
|
# this is only a problem insofar the existing NodeReduction has to be deleted and replaced also in the possibleOperations
|
|
|
|
invalidate_caches!(graph, node.nodeReduction)
|
|
|
|
end
|
|
|
|
node.nodeReduction = nr
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return nothing
|
2023-08-21 12:54:45 +02:00
|
|
|
end
|
|
|
|
|
2023-08-29 12:57:46 +02:00
|
|
|
"""
|
|
|
|
find_splits!(graph::DAG, node::Node)
|
|
|
|
|
|
|
|
Find the node split of the given node. The function pushes the found [`NodeSplit`](@ref) (if any) everywhere it needs to be and returns nothing.
|
|
|
|
"""
|
2023-08-21 12:54:45 +02:00
|
|
|
function find_splits!(graph::DAG, node::Node)
|
2023-08-25 10:48:22 +02:00
|
|
|
if !ismissing(node.nodeSplit)
|
|
|
|
return nothing
|
|
|
|
end
|
2023-08-23 19:28:45 +02:00
|
|
|
|
2023-08-25 10:48:22 +02:00
|
|
|
if (can_split(node))
|
|
|
|
ns = NodeSplit(node)
|
|
|
|
push!(graph.possibleOperations.nodeSplits, ns)
|
|
|
|
node.nodeSplit = ns
|
|
|
|
end
|
2023-08-21 12:54:45 +02:00
|
|
|
|
2023-08-25 10:48:22 +02:00
|
|
|
return nothing
|
2023-08-21 12:54:45 +02:00
|
|
|
end
|
|
|
|
|
2023-08-29 12:57:46 +02:00
|
|
|
"""
|
|
|
|
clean_node!(graph::DAG, node::Node)
|
|
|
|
|
|
|
|
Sort this node's parent and child sets, then find fusions, reductions and splits involving it. Needs to be called after the node was changed in some way.
|
|
|
|
"""
|
2023-08-21 12:54:45 +02:00
|
|
|
function clean_node!(graph::DAG, node::Node)
|
2023-08-25 10:48:22 +02:00
|
|
|
sort_node!(node)
|
|
|
|
|
|
|
|
find_fusions!(graph, node)
|
|
|
|
find_reductions!(graph, node)
|
2023-08-29 12:57:46 +02:00
|
|
|
find_splits!(graph, node)
|
|
|
|
|
|
|
|
return nothing
|
2023-08-21 12:54:45 +02:00
|
|
|
end
|