WIP regenerate possible operations
This commit is contained in:
parent
d24d354fa0
commit
0cd83fedd9
@ -14,10 +14,13 @@ include("graph_operations.jl")
|
||||
include("import.jl")
|
||||
include("utility.jl")
|
||||
|
||||
include("abc_model/tasks.jl")
|
||||
include("abc_model/task_functions.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 NodeFusion, NodeReduction, NodeSplit, push_operation!, pop_operation!, can_pop, reset_graph!, generate_options
|
||||
export NodeFusion, NodeReduction, NodeSplit, push_operation!, pop_operation!, can_pop, reset_graph!, get_operations
|
||||
export import_txt
|
||||
|
||||
export ==, in, show
|
||||
|
21
src/abc_model/task_functions.jl
Normal file
21
src/abc_model/task_functions.jl
Normal file
@ -0,0 +1,21 @@
|
||||
# define compute_efforts tasks computation
|
||||
# put some "random" numbers here for now
|
||||
compute_effort(t::ComputeTaskS1) = 10
|
||||
compute_effort(t::ComputeTaskS2) = 10
|
||||
compute_effort(t::ComputeTaskU) = 6
|
||||
compute_effort(t::ComputeTaskV) = 20
|
||||
compute_effort(t::ComputeTaskP) = 15
|
||||
compute_effort(t::ComputeTaskSum) = 1
|
||||
|
||||
function show(io::IO, t::DataTask)
|
||||
print(io, "Data", t.data)
|
||||
end
|
||||
|
||||
show(io::IO, t::ComputeTaskS1) = print("ComputeS1")
|
||||
show(io::IO, t::ComputeTaskS2) = print("ComputeS2")
|
||||
show(io::IO, t::ComputeTaskP) = print("ComputeP")
|
||||
show(io::IO, t::ComputeTaskU) = print("ComputeU")
|
||||
show(io::IO, t::ComputeTaskV) = print("ComputeV")
|
||||
show(io::IO, t::ComputeTaskSum) = print("ComputeSum")
|
||||
|
||||
copy(t::DataTask) = DataTask(t.data)
|
27
src/abc_model/tasks.jl
Normal file
27
src/abc_model/tasks.jl
Normal file
@ -0,0 +1,27 @@
|
||||
struct DataTask <: AbstractDataTask
|
||||
data::UInt64
|
||||
end
|
||||
|
||||
# S task with 1 child
|
||||
struct ComputeTaskS1 <: AbstractComputeTask
|
||||
end
|
||||
|
||||
# S task with 2 children
|
||||
struct ComputeTaskS2 <: AbstractComputeTask
|
||||
end
|
||||
|
||||
# P task with 0 children
|
||||
struct ComputeTaskP <: AbstractComputeTask
|
||||
end
|
||||
|
||||
# v task with 2 children
|
||||
struct ComputeTaskV <: AbstractComputeTask
|
||||
end
|
||||
|
||||
# u task with 1 child
|
||||
struct ComputeTaskU <: AbstractComputeTask
|
||||
end
|
||||
|
||||
# task that sums all its inputs, n children
|
||||
struct ComputeTaskSum <: AbstractComputeTask
|
||||
end
|
23
src/graph.jl
23
src/graph.jl
@ -23,7 +23,7 @@ abstract type Operation end
|
||||
abstract type AppliedOperation end
|
||||
|
||||
struct NodeFusion <: Operation
|
||||
input::Tuple{ComputeTaskNode,DataTaskNode,ComputeTaskNode}
|
||||
input::Tuple{ComputeTaskNode, DataTaskNode, ComputeTaskNode}
|
||||
end
|
||||
|
||||
struct AppliedNodeFusion <: AppliedOperation
|
||||
@ -50,17 +50,20 @@ struct AppliedNodeSplit <: AppliedOperation
|
||||
end
|
||||
|
||||
|
||||
const PossibleOperations = NamedTuple{
|
||||
(:nodeFusions, :nodeReductions, :nodeSplits),
|
||||
Tuple{Vector{NodeFusion}, Vector{NodeReduction}, Vector{NodeSplit}}
|
||||
}
|
||||
mutable struct PossibleOperations
|
||||
nodeFusions::Vector{NodeFusion}
|
||||
nodeReductions::Vector{NodeReduction}
|
||||
nodeSplits::Vector{NodeSplit}
|
||||
dirty::Bool
|
||||
end
|
||||
|
||||
function PossibleOperations()
|
||||
return (
|
||||
nodeFusions = Vector{NodeFusion}(),
|
||||
nodeReductions = Vector{NodeReduction}(),
|
||||
nodeSplits = Vector{NodeSplit}()
|
||||
)::PossibleOperations
|
||||
return PossibleOperations(
|
||||
Vector{NodeFusion}(),
|
||||
Vector{NodeReduction}(),
|
||||
Vector{NodeSplit}(),
|
||||
false
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
@ -67,6 +67,7 @@ function insert_node!(graph::DAG, node::Node, track=true)
|
||||
push!(graph.nodes, node)
|
||||
|
||||
if (track) push!(graph.diff.addedNodes, node) end
|
||||
graph.possibleOperations.dirty = true
|
||||
return node
|
||||
end
|
||||
|
||||
@ -76,6 +77,7 @@ function insert_edge!(graph::DAG, edge::Edge, track=true)
|
||||
push!(edge.edge[2].children, edge.edge[1])
|
||||
|
||||
if (track) push!(graph.diff.addedEdges, edge) end
|
||||
graph.possibleOperations.dirty = true
|
||||
return edge
|
||||
end
|
||||
|
||||
@ -83,6 +85,7 @@ function remove_node!(graph::DAG, node::Node, track=true)
|
||||
delete!(graph.nodes, node)
|
||||
|
||||
if (track) push!(graph.diff.removedNodes, node) end
|
||||
graph.possibleOperations.dirty = true
|
||||
return nothing
|
||||
end
|
||||
|
||||
@ -91,6 +94,7 @@ function remove_edge!(graph::DAG, edge::Edge, track=true)
|
||||
filter!(x -> x != edge.edge[1], edge.edge[2].children)
|
||||
|
||||
if (track) push!(graph.diff.removedEdges, edge) end
|
||||
graph.possibleOperations.dirty = true
|
||||
return nothing
|
||||
end
|
||||
|
||||
|
@ -264,7 +264,11 @@ function generate_options(graph::DAG)
|
||||
end
|
||||
child_node = pop!(node_children)
|
||||
|
||||
push!(options.nodeFusions, NodeFusion((child_node, node, parent_node)))
|
||||
nf = NodeFusion((child_node, node, parent_node))
|
||||
push!(options.nodeFusions, nf)
|
||||
push!(child_node.operations, nf)
|
||||
push!(node.operations, nf)
|
||||
push!(parent_node.operations, nf)
|
||||
end
|
||||
end
|
||||
|
||||
@ -278,29 +282,48 @@ function generate_options(graph::DAG)
|
||||
|
||||
push!(visitedNodes, node)
|
||||
|
||||
reductionVector = missing
|
||||
reductionVector = nothing
|
||||
# possible reductions are with nodes that are partners, i.e. parents of children
|
||||
for partner in partners(node)
|
||||
if can_reduce(node, partner)
|
||||
if reductionVector == missing
|
||||
if reductionVector === nothing
|
||||
# only when there's at least one reduction partner, insert the vector
|
||||
reductionVector = Vector{Node}
|
||||
push!(reductionVector, node)
|
||||
push!(options.nodeReductions, NodeReduction(reductionVector))
|
||||
end
|
||||
|
||||
push!(reductionVector, partner)
|
||||
push!(visitedNodes, partner)
|
||||
end
|
||||
end
|
||||
|
||||
if reductionVector !== nothing
|
||||
nr = NodeReduction(reductionVector)
|
||||
push!(options.nodeReductions, nr)
|
||||
for node in reductionVector
|
||||
push!(node.operations, nr)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# find possible node splits
|
||||
for node in graph.nodes
|
||||
if (can_split(node))
|
||||
push!(options.nodeSplits, NodeSplit(node))
|
||||
ns = NodeSplit(node)
|
||||
push!(options.nodeSplits, ns)
|
||||
push!(node.operations, ns)
|
||||
end
|
||||
end
|
||||
|
||||
return options
|
||||
options.dirty = false
|
||||
|
||||
graph.possibleOperations = options
|
||||
end
|
||||
|
||||
function get_operations(graph::DAG)
|
||||
if (graph.possibleOperations.dirty)
|
||||
generate_options(graph)
|
||||
end
|
||||
|
||||
return graph.possibleOperations
|
||||
end
|
@ -35,5 +35,5 @@ function ==(e1::Edge, e2::Edge)
|
||||
end
|
||||
|
||||
copy(id::Base.UUID) = Base.UUID(id.value)
|
||||
copy(n::ComputeTaskNode) = ComputeTaskNode(copy(n.task), copy(n.parents), copy(n.children), copy(n.id))
|
||||
copy(n::DataTaskNode) = DataTaskNode(copy(n.task), copy(n.parents), copy(n.children), copy(n.id))
|
||||
copy(n::ComputeTaskNode) = ComputeTaskNode(copy(n.task), copy(n.parents), copy(n.children), copy(n.id), copy(n.operations))
|
||||
copy(n::DataTaskNode) = DataTaskNode(copy(n.task), copy(n.parents), copy(n.children), copy(n.id), copy(n.operations))
|
||||
|
12
src/nodes.jl
12
src/nodes.jl
@ -5,6 +5,10 @@ rng = Random.MersenneTwister(0)
|
||||
|
||||
abstract type Node end
|
||||
|
||||
# declare this type here because it's needed
|
||||
# the specific operations are declared in graph.jl
|
||||
abstract type Operation end
|
||||
|
||||
struct DataTaskNode <: Node
|
||||
task::AbstractDataTask
|
||||
|
||||
@ -15,6 +19,9 @@ struct DataTaskNode <: Node
|
||||
# need a unique identifier unique to every *constructed* node
|
||||
# however, it can be copied when splitting a node
|
||||
id::Base.UUID
|
||||
|
||||
# a vector holding references to the graph operations involving this node
|
||||
operations::Vector{Operation}
|
||||
end
|
||||
|
||||
# same as DataTaskNode
|
||||
@ -23,10 +30,11 @@ struct ComputeTaskNode <: Node
|
||||
parents::Vector{Node}
|
||||
children::Vector{Node}
|
||||
id::Base.UUID
|
||||
operations::Vector{Operation}
|
||||
end
|
||||
|
||||
DataTaskNode(t::AbstractDataTask) = DataTaskNode(t, Vector{Node}(), Vector{Node}(), UUIDs.uuid1(rng))
|
||||
ComputeTaskNode(t::AbstractComputeTask) = ComputeTaskNode(t, Vector{Node}(), Vector{Node}(), UUIDs.uuid1(rng))
|
||||
DataTaskNode(t::AbstractDataTask) = DataTaskNode(t, Vector{Node}(), Vector{Node}(), UUIDs.uuid1(rng), Vector{Operation}())
|
||||
ComputeTaskNode(t::AbstractComputeTask) = ComputeTaskNode(t, Vector{Node}(), Vector{Node}(), UUIDs.uuid1(rng), Vector{Operation}())
|
||||
|
||||
struct Edge
|
||||
# edge points from child to parent
|
||||
|
@ -17,14 +17,6 @@ data(t::AbstractDataTask) = getfield(t, :data)
|
||||
|
||||
data(t::AbstractComputeTask) = 0
|
||||
|
||||
# define compute_efforts tasks computation
|
||||
# put some "random" numbers here for now
|
||||
compute_effort(t::ComputeTaskS1) = 10
|
||||
compute_effort(t::ComputeTaskS2) = 10
|
||||
compute_effort(t::ComputeTaskU) = 6
|
||||
compute_effort(t::ComputeTaskV) = 20
|
||||
compute_effort(t::ComputeTaskP) = 15
|
||||
compute_effort(t::ComputeTaskSum) = 1
|
||||
function compute_effort(t::FusedComputeTask)
|
||||
(T1, T2) = collect(typeof(t).parameters)
|
||||
return compute_effort(T1()) + compute_effort(T2())
|
||||
@ -40,17 +32,6 @@ function compute_intensity(t::AbstractTask)::UInt64
|
||||
return compute_effort(t) / data(t)
|
||||
end
|
||||
|
||||
function show(io::IO, t::DataTask)
|
||||
print(io, "Data", t.data)
|
||||
end
|
||||
|
||||
show(io::IO, t::ComputeTaskS1) = print("ComputeS1")
|
||||
show(io::IO, t::ComputeTaskS2) = print("ComputeS2")
|
||||
show(io::IO, t::ComputeTaskP) = print("ComputeP")
|
||||
show(io::IO, t::ComputeTaskU) = print("ComputeU")
|
||||
show(io::IO, t::ComputeTaskV) = print("ComputeV")
|
||||
show(io::IO, t::ComputeTaskSum) = print("ComputeSum")
|
||||
|
||||
function show(io::IO, t::FusedComputeTask)
|
||||
(T1, T2) = get_types(t)
|
||||
print(io, "ComputeFuse(", T1(), ", ", T2(), ")")
|
||||
@ -68,5 +49,5 @@ function ==(t1::AbstractDataTask, t2::AbstractDataTask)
|
||||
return data(t1) == data(t2)
|
||||
end
|
||||
|
||||
copy(t::DataTask) = DataTask(t.data)
|
||||
copy(t::AbstractDataTask) = error("Need to implement copying for your data tasks!")
|
||||
copy(t::AbstractComputeTask) = typeof(t)()
|
||||
|
28
src/tasks.jl
28
src/tasks.jl
@ -3,34 +3,6 @@ abstract type AbstractTask end
|
||||
abstract type AbstractComputeTask <: AbstractTask end
|
||||
abstract type AbstractDataTask <: AbstractTask end
|
||||
|
||||
struct DataTask <: AbstractDataTask
|
||||
data::UInt64
|
||||
end
|
||||
|
||||
# S task with 1 child
|
||||
struct ComputeTaskS1 <: AbstractComputeTask
|
||||
end
|
||||
|
||||
# S task with 2 children
|
||||
struct ComputeTaskS2 <: AbstractComputeTask
|
||||
end
|
||||
|
||||
# P task with 0 children
|
||||
struct ComputeTaskP <: AbstractComputeTask
|
||||
end
|
||||
|
||||
# v task with 2 children
|
||||
struct ComputeTaskV <: AbstractComputeTask
|
||||
end
|
||||
|
||||
# u task with 1 child
|
||||
struct ComputeTaskU <: AbstractComputeTask
|
||||
end
|
||||
|
||||
# task that sums all its inputs, n children
|
||||
struct ComputeTaskSum <: AbstractComputeTask
|
||||
end
|
||||
|
||||
struct FusedComputeTask{T1<:AbstractComputeTask, T2<:AbstractComputeTask} <: AbstractComputeTask
|
||||
end
|
||||
|
||||
|
@ -12,7 +12,7 @@ function test_known_graphs()
|
||||
@test props.compute_effort == 185
|
||||
@test props.data == 102
|
||||
|
||||
@test length(generate_options(g_ABAB).nodeFusions) == 10
|
||||
@test length(get_operations(g_ABAB).nodeFusions) == 10
|
||||
|
||||
test_node_fusion(g_ABAB)
|
||||
test_random_walk(g_ABAB, 100)
|
||||
@ -32,7 +32,7 @@ end
|
||||
function test_node_fusion(g::DAG)
|
||||
props = graph_properties(g)
|
||||
|
||||
options = generate_options(g)
|
||||
options = get_operations(g)
|
||||
|
||||
nodes_number = length(g.nodes)
|
||||
data = props.data
|
||||
@ -53,7 +53,7 @@ function test_node_fusion(g::DAG)
|
||||
data = props.data
|
||||
compute_effort = props.compute_effort
|
||||
|
||||
options = generate_options(g)
|
||||
options = get_operations(g)
|
||||
end
|
||||
end
|
||||
|
||||
@ -70,7 +70,7 @@ function test_random_walk(g::DAG, n::Int64)
|
||||
# choose push or pop
|
||||
if rand(Bool)
|
||||
# push
|
||||
opt = generate_options(g)
|
||||
opt = get_operations(g)
|
||||
|
||||
# choose one of fuse/split/reduce
|
||||
option = rand(1:3)
|
||||
|
Loading…
x
Reference in New Issue
Block a user