WIP
This commit is contained in:
parent
5bf660618d
commit
2a1b161462
@ -4,5 +4,6 @@ authors = ["Anton Reinhard <anton.reinhard@wandelbots.com>"]
|
||||
version = "0.1.0"
|
||||
|
||||
[deps]
|
||||
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
|
||||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||
|
2
examples/AB->AB.txt
Normal file
2
examples/AB->AB.txt
Normal file
@ -0,0 +1,2 @@
|
||||
['A1', 'B1', 'A2', 'B2', 'C(A1,B1)', 'M(C(A1,B1),A2,B2)', 'C(A1,B2)', 'M(C(A1,B2),B1,A2)', '+']
|
||||
[('A1', 'C(A1,B1)'), ('A1', 'C(A1,B2)'), ('B1', 'C(A1,B1)'), ('B1', 'M(C(A1,B2),B1,A2)'), ('A2', 'M(C(A1,B1),A2,B2)'), ('A2', 'M(C(A1,B2),B1,A2)'), ('B2', 'M(C(A1,B1),A2,B2)'), ('B2', 'C(A1,B2)'), ('C(A1,B1)', 'M(C(A1,B1),A2,B2)'), ('M(C(A1,B1),A2,B2)', '+'), ('C(A1,B2)', 'M(C(A1,B2),B1,A2)'), ('M(C(A1,B2),B1,A2)', '+')]
|
2
examples/AB->ABBB.txt
Normal file
2
examples/AB->ABBB.txt
Normal file
File diff suppressed because one or more lines are too long
2
examples/AB->ABBBBB.txt
Normal file
2
examples/AB->ABBBBB.txt
Normal file
File diff suppressed because one or more lines are too long
2
examples/AB->ABBBBBBB.txt
Normal file
2
examples/AB->ABBBBBBB.txt
Normal file
File diff suppressed because one or more lines are too long
BIN
examples/AB->ABBBBBBBBB.txt
Normal file
BIN
examples/AB->ABBBBBBBBB.txt
Normal file
Binary file not shown.
2
examples/ABAB->ABAB.txt
Normal file
2
examples/ABAB->ABAB.txt
Normal file
File diff suppressed because one or more lines are too long
2
examples/ABAB->ABC.txt
Normal file
2
examples/ABAB->ABC.txt
Normal file
File diff suppressed because one or more lines are too long
@ -1,3 +1,5 @@
|
||||
using DataStructures
|
||||
|
||||
in(node::Node, graph::DAG) = node in graph.nodes
|
||||
in(edge::Edge, graph::DAG) = edge in graph.edges
|
||||
|
||||
@ -44,8 +46,8 @@ function parents(graph::DAG, node::Node)
|
||||
return result
|
||||
end
|
||||
|
||||
is_entry_node(graph::DAG, node::Node) = size(children(graph, node)) == 0
|
||||
is_exit_node(graph::DAG, node::Node) = size(parents(graph, node)) == 0
|
||||
is_entry_node(graph::DAG, node::Node) = length(children(graph, node)) == 0
|
||||
is_exit_node(graph::DAG, node::Node) = length(parents(graph, node)) == 0
|
||||
|
||||
function insert_node(graph::DAG, node::Node)
|
||||
push!(graph.nodes, node)
|
||||
@ -100,6 +102,25 @@ function get_exit_node(graph::DAG)
|
||||
error("The given graph has no exit node! It is either empty or not acyclic!")
|
||||
end
|
||||
|
||||
# check whether the given graph is connected
|
||||
function is_valid(graph::DAG)
|
||||
nodeQueue = Deque{Node}()
|
||||
push!(nodeQueue, get_exit_node(graph))
|
||||
seenNodes = Set{Node}()
|
||||
|
||||
while ! isempty(nodeQueue)
|
||||
current = pop!(nodeQueue)
|
||||
push!(seenNodes, current)
|
||||
|
||||
childrenNodes = children(graph, current)
|
||||
for child in childrenNodes
|
||||
push!(nodeQueue, child)
|
||||
end
|
||||
end
|
||||
|
||||
return length(seenNodes) == length(graph.nodes)
|
||||
end
|
||||
|
||||
function show_nodes(io, graph::DAG)
|
||||
print(io, "[")
|
||||
first = true
|
||||
@ -131,10 +152,34 @@ end
|
||||
function show(io::IO, graph::DAG)
|
||||
println(io, "Graph:")
|
||||
print(io, " Nodes: ")
|
||||
show_nodes(io, graph)
|
||||
if length(graph.nodes) <= 20
|
||||
show_nodes(io, graph)
|
||||
else
|
||||
nodeDict = Dict{Type, Int64}()
|
||||
for node in graph.nodes
|
||||
if haskey(nodeDict, typeof(node.task))
|
||||
nodeDict[typeof(node.task)] = nodeDict[typeof(node.task)] + 1
|
||||
else
|
||||
nodeDict[typeof(node.task)] = 1
|
||||
end
|
||||
end
|
||||
first = true
|
||||
for (type, number) in zip(keys(nodeDict), values(nodeDict))
|
||||
if first
|
||||
first = false
|
||||
else
|
||||
print(", ")
|
||||
end
|
||||
print(type, ": ", number)
|
||||
end
|
||||
end
|
||||
println(io)
|
||||
print(io, " Edges: ")
|
||||
show_edges(io, graph)
|
||||
if length(graph.edges) <= 40
|
||||
show_edges(io, graph)
|
||||
else
|
||||
print(length(graph.edges))
|
||||
end
|
||||
println(io)
|
||||
println(io, " Total Compute Effort: ", compute_effort(graph))
|
||||
println(io, " Total Data Transfer: ", data(graph))
|
||||
|
127
src/import.jl
Normal file
127
src/import.jl
Normal file
@ -0,0 +1,127 @@
|
||||
# functions for importing DAGs from a file
|
||||
|
||||
regex_a = r"^[A-C]\d+$" # Regex for the initial particles
|
||||
regex_c = r"^[A-C]\(([^']*),([^']*)\)$" # Regex for the combinations of 2 particles
|
||||
regex_m = r"^M\(([^']*),([^']*),([^']*)\)$" # Regex for the combinations of 3 particles
|
||||
regex_plus = r"^\+$" # Regex for the sum
|
||||
|
||||
function parse_nodes(input::AbstractString)
|
||||
regex = r"'([^']*)'"
|
||||
matches = eachmatch(regex, input)
|
||||
output = [match.captures[1] for match in matches]
|
||||
return output
|
||||
end
|
||||
|
||||
function parse_edges(input::AbstractString)
|
||||
regex = r"\('([^']*)', '([^']*)'\)"
|
||||
matches = eachmatch(regex, input)
|
||||
output = [(match.captures[1], match.captures[2]) for match in matches]
|
||||
return output
|
||||
end
|
||||
|
||||
function importTxt(filename::String)
|
||||
file = open(filename, "r")
|
||||
|
||||
nodes_string = readline(file)
|
||||
nodes = parse_nodes(nodes_string)
|
||||
|
||||
close(file)
|
||||
|
||||
graph = DAG()
|
||||
|
||||
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))
|
||||
|
||||
# remember the data out nodes for connection
|
||||
dataOutNodes = Dict()
|
||||
|
||||
for node in nodes
|
||||
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
|
||||
|
||||
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))
|
||||
|
||||
# remember the data_out node for future edges
|
||||
dataOutNodes[node] = data_out
|
||||
elseif occursin(regex_c, node)
|
||||
capt = match(regex_c, node)
|
||||
|
||||
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)))
|
||||
|
||||
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)))
|
||||
|
||||
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(data_S_v, compute_v))
|
||||
else
|
||||
insert_edge(graph, make_edge(dataOutNodes[capt.captures[1]], compute_v))
|
||||
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)))
|
||||
|
||||
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(data_S_v, compute_v))
|
||||
else
|
||||
insert_edge(graph, make_edge(dataOutNodes[capt.captures[2]], compute_v))
|
||||
end
|
||||
|
||||
insert_edge(graph, make_edge(compute_v, data_out))
|
||||
dataOutNodes[node] = data_out
|
||||
|
||||
elseif occursin(regex_m, node)
|
||||
# assume for now that only the first particle of the three is combined and the other two are "original" ones
|
||||
capt = match(regex_m, node)
|
||||
in1 = capt.captures[1]
|
||||
in2 = capt.captures[2]
|
||||
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)))
|
||||
|
||||
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))
|
||||
|
||||
# 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)))
|
||||
|
||||
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_out, sum_node))
|
||||
elseif occursin(regex_plus, node)
|
||||
println("Found sum node, end")
|
||||
else
|
||||
error("Unknown node '", node, "' while reading from file ", filename)
|
||||
end
|
||||
end
|
||||
|
||||
# don't actually need to read the edges
|
||||
return graph
|
||||
end
|
@ -10,11 +10,13 @@ include("task_functions.jl")
|
||||
include("node_functions.jl")
|
||||
include("graph_functions.jl")
|
||||
include("graph_optimizations.jl")
|
||||
include("import.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, get_exit_node
|
||||
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, data, compute_effort, compute_intensity, get_exit_node, is_valid
|
||||
export node_fusion, node_reduction, node_split, generate_options
|
||||
export importTxt
|
||||
|
||||
export ==, in, show
|
||||
|
||||
|
@ -24,6 +24,7 @@ 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())
|
||||
@ -48,6 +49,7 @@ 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)
|
||||
|
@ -27,6 +27,10 @@ end
|
||||
struct ComputeTaskU <: AbstractComputeTask
|
||||
end
|
||||
|
||||
# task that sums all its inputs, n children
|
||||
struct ComputeTaskSum <: AbstractComputeTask
|
||||
end
|
||||
|
||||
struct FusedComputeTask{T1<:AbstractComputeTask, T2<:AbstractComputeTask} <: AbstractComputeTask
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user