From 92f59110ed2595dedbd527cf557fcd953ad36fc5 Mon Sep 17 00:00:00 2001 From: Anton Reinhard Date: Wed, 23 Aug 2023 12:51:25 +0200 Subject: [PATCH] Add node reduction unit test and fix bugs --- results/temp.md | 17 ++ src/MetagraphOptimization.jl | 1 + src/graph.jl | 4 - src/operations/apply.jl | 65 +++---- src/operations/clean.jl | 67 +++----- src/operations/print.jl | 38 +++++ src/operations/utility.jl | 6 +- test/node_reduction.jl | 94 +++++++++++ test/runtests.jl | 11 +- test/unit_tests_graph.jl | 317 +++++++++++++++++------------------ test/unit_tests_nodes.jl | 52 +++--- test/unit_tests_tasks.jl | 90 +++++----- test/unit_tests_utility.jl | 14 +- 13 files changed, 453 insertions(+), 323 deletions(-) create mode 100644 results/temp.md create mode 100644 src/operations/print.jl create mode 100644 test/node_reduction.jl diff --git a/results/temp.md b/results/temp.md new file mode 100644 index 0000000..06c38f0 --- /dev/null +++ b/results/temp.md @@ -0,0 +1,17 @@ +(AB->ABBBBBBB, 1) 1.620 s (5909018 allocations: 656.78 MiB) +(AB->ABBBBBBB, 2) 758.299 ms (5909088 allocations: 765.78 MiB) +(AB->ABBBBBBB, 3) 595.788 ms (5909161 allocations: 748.89 MiB) +(AB->ABBBBBBB, 4) 849.007 ms (5880250 allocations: 762.00 MiB) +(AB->ABBBBBBB, 5) 563.021 ms (5880332 allocations: 781.17 MiB) +(AB->ABBBBBBB, 6) 526.095 ms (5880419 allocations: 818.32 MiB) +(AB->ABBBBBBB, 7) 586.057 ms (5880482 allocations: 826.36 MiB) +(AB->ABBBBBBB, 8) 504.515 ms (5880542 allocations: 796.58 MiB) + +(AB->ABBBBBBB, 1) 1.537 s (5596315 allocations: 616.81 MiB) +(AB->ABBBBBBB, 2) 826.918 ms (5596385 allocations: 725.81 MiB) +(AB->ABBBBBBB, 3) 538.787 ms (5596457 allocations: 708.92 MiB) +(AB->ABBBBBBB, 4) 918.853 ms (5596528 allocations: 725.08 MiB) +(AB->ABBBBBBB, 5) 511.959 ms (5596606 allocations: 744.25 MiB) +(AB->ABBBBBBB, 6) 887.160 ms (5596691 allocations: 763.42 MiB) +(AB->ABBBBBBB, 7) 898.757 ms (5596762 allocations: 789.91 MiB) +(AB->ABBBBBBB, 8) 497.545 ms (5596820 allocations: 759.66 MiB) diff --git a/src/MetagraphOptimization.jl b/src/MetagraphOptimization.jl index bf8e60f..b51f43c 100644 --- a/src/MetagraphOptimization.jl +++ b/src/MetagraphOptimization.jl @@ -37,6 +37,7 @@ include("operations/apply.jl") include("operations/clean.jl") include("operations/find.jl") include("operations/get.jl") +include("operations/print.jl") include("graph_interface.jl") diff --git a/src/graph.jl b/src/graph.jl index 40dcf39..92ed7f3 100644 --- a/src/graph.jl +++ b/src/graph.jl @@ -33,10 +33,6 @@ end struct NodeReduction <: Operation input::Vector{Node} - - # these inputs can (and do) get very large in large graphs, so we need a better way to compare equality between them - # only node reductions with the same id will be considered equal (the id can be copied) - id::UUID end struct AppliedNodeReduction <: AppliedOperation diff --git a/src/operations/apply.jl b/src/operations/apply.jl index ac12cd9..3e1e61c 100644 --- a/src/operations/apply.jl +++ b/src/operations/apply.jl @@ -25,7 +25,7 @@ function apply_operation!(graph::DAG, operation::NodeFusion) end function apply_operation!(graph::DAG, operation::NodeReduction) - diff = node_reduction!(graph, operation.input[1], operation.input[2]) + diff = node_reduction!(graph, operation.input) return AppliedNodeReduction(operation, diff) end @@ -147,48 +147,57 @@ function node_fusion!(graph::DAG, n1::ComputeTaskNode, n2::DataTaskNode, n3::Com return get_snapshot_diff(graph) end -function node_reduction!(graph::DAG, n1::Node, n2::Node) +function node_reduction!(graph::DAG, nodes::Vector{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=# + t = typeof(nodes[1].task) + for n in nodes + if n ∉ graph + error("[Node Reduction] The given nodes are not part of the given graph") + end - #=if typeof(n1) != typeof(n2) - error("[Node Reduction] The given nodes are not of the same type") - end=# - - # save n2 parents and children - n2_children = children(n2) - n2_parents = Set(n2.parents) - - #=if Set(n2_children) != Set(n1.children) - error("[Node Reduction] The given nodes do not have equal prerequisite nodes which is required for node reduction") - end=# - - # remove n2 and all its parents and children - for child in n2_children - remove_edge!(graph, make_edge(child, n2)) + if typeof(n.task) != t + error("[Node Reduction] The given nodes are not of the same type") + end end - for parent in n2_parents - remove_edge!(graph, make_edge(n2, parent)) + n1 = nodes[1] + n1_children = children(n1) + for n in nodes + if Set(n1_children) != Set(n.children) + error("[Node Reduction] The given nodes do not have equal prerequisite nodes which is required for node reduction") + end end - for parent in n1.parents - # delete parents in n1 that already exist in n2 - delete!(n2_parents, parent) + n1_parents = Set(n1.parents) + new_parents = Set{Node}() + + # remove all of the nodes' parents and children and the nodes themselves (except for first node) + for i in 2:length(nodes) + n = nodes[i] + for child in n1_children + remove_edge!(graph, make_edge(child, n)) + end + + for parent in parents(n) + remove_edge!(graph, make_edge(n, parent)) + + # collect all parents + push!(new_parents, parent) + end + + remove_node!(graph, n) end - for parent in n2_parents + setdiff!(new_parents, n1_parents) + + for parent in new_parents # now add parents of n2 to n1 without duplicates insert_edge!(graph, make_edge(n1, parent)) end - remove_node!(graph, n2) - return get_snapshot_diff(graph) end diff --git a/src/operations/clean.jl b/src/operations/clean.jl index ea85ce1..56fb249 100644 --- a/src/operations/clean.jl +++ b/src/operations/clean.jl @@ -3,6 +3,13 @@ # function to find node fusions involving the given node if it's a data node # pushes the found fusion everywhere it needs to be and returns nothing function find_fusions!(graph::DAG, node::DataTaskNode) + # if there is already a fusion here, skip + for op in node.operations + if typeof(op) <: NodeFusion + return nothing + end + end + if length(node.parents) != 1 || length(node.children) != 1 return nothing end @@ -27,61 +34,29 @@ function find_fusions!(graph::DAG, node::DataTaskNode) return nothing end -# function to find node fusions involving the given node if it's a compute node -# pushes the found fusion(s) everywhere it needs to be and returns nothing + function find_fusions!(graph::DAG, node::ComputeTaskNode) - # for loop that always runs once for a scoped block we can break out of - for _ in 1:1 - # assume this node as child of the chain - if length(node.parents) != 1 - break - end - node2 = first(node.parents) - if length(node2.parents) != 1 || length(node2.children) != 1 - break - end - node3 = first(node2.parents) + # just find fusions in neighbouring DataTaskNodes - #=if !(node2 in graph) || !(node3 in graph) - error("Parents/Children that are not in the graph!!!") - end=# - - nf = NodeFusion((node, node2, node3)) - push!(graph.possibleOperations.nodeFusions, nf) - push!(node.operations, nf) - push!(node2.operations, nf) - push!(node3.operations, nf) + for child in node.children + find_fusions!(graph, child) end - for _ in 1:1 - # assume this node as parent of the chain - if length(node.children) < 1 - break - end - node2 = first(node.children) - if length(node2.parents) != 1 || length(node2.children) != 1 - break - end - node1 = first(node2.children) - if (length(node1.parents) > 1) - break - end - - #=if !(node2 in graph) || !(node1 in graph) - error("Parents/Children that are not in the graph!!!") - end=# - - nf = NodeFusion((node1, node2, node)) - push!(graph.possibleOperations.nodeFusions, nf) - push!(node1.operations, nf) - push!(node2.operations, nf) - push!(node.operations, nf) + for parent in node.parents + find_fusions!(graph, parent) end return nothing end function find_reductions!(graph::DAG, node::Node) + # there can only be one reduction per node, avoid adding duplicates + for op in node.operations + if typeof(op) <: NodeReduction + return nothing + end + end + reductionVector = nothing # possible reductions are with nodes that are partners, i.e. parents of children partners_ = partners(node) @@ -121,6 +96,8 @@ end # "clean" the operations on a dirty node function clean_node!(graph::DAG, node::Node) + sort_node!(node) + find_fusions!(graph, node) find_reductions!(graph, node) find_splits!(graph, node) diff --git a/src/operations/print.jl b/src/operations/print.jl new file mode 100644 index 0000000..742afb9 --- /dev/null +++ b/src/operations/print.jl @@ -0,0 +1,38 @@ +function show(io::IO, ops::PossibleOperations) + print(io, length(ops.nodeFusions)) + println(io, " Node Fusions: ") + for nf in ops.nodeFusions + println(io, " - ", nf) + end + print(io, length(ops.nodeReductions)) + println(io, " Node Reductions: ") + for nr in ops.nodeReductions + println(io, " - ", nr) + end + print(io, length(ops.nodeSplits)) + println(io, " Node Splits: ") + for ns in ops.nodeSplits + println(io, " - ", ns) + end +end + +function show(io::IO, op::NodeReduction) + print(io, "NR: ") + print(io, length(op.input)) + print(io, "x") + print(io, op.input[1].task) +end + +function show(io::IO, op::NodeSplit) + print(io, "NS: ") + print(io, op.input.task) +end + +function show(io::IO, op::NodeFusion) + print(io, "NF: ") + print(io, op.input[1].task) + print(io, "->") + print(io, op.input[2].task) + print(io, "->") + print(io, op.input[3].task) +end diff --git a/src/operations/utility.jl b/src/operations/utility.jl index 4ce7b3a..6bda2fe 100644 --- a/src/operations/utility.jl +++ b/src/operations/utility.jl @@ -96,14 +96,12 @@ function ==(op1::NodeFusion, op2::NodeFusion) end function ==(op1::NodeReduction, op2::NodeReduction) - # only test the ids against each other - return op1.id == op2.id + # node reductions are equal exactly if their first input is the same + return op1.input[1].id == op2.input[1].id end function ==(op1::NodeSplit, op2::NodeSplit) return op1.input == op2.input end -NodeReduction(input::Vector{Node}) = NodeReduction(input, UUIDs.uuid1(rng[threadid()])) - copy(id::UUID) = UUID(id.value) diff --git a/test/node_reduction.jl b/test/node_reduction.jl new file mode 100644 index 0000000..5b060df --- /dev/null +++ b/test/node_reduction.jl @@ -0,0 +1,94 @@ +import MetagraphOptimization.insert_node! +import MetagraphOptimization.insert_edge! +import MetagraphOptimization.make_node +import MetagraphOptimization.make_edge + +@testset "Unit Tests Node Reduction" begin + graph = MetagraphOptimization.DAG() + + d_exit = insert_node!(graph, make_node(DataTask(10)), false) + + s0 = insert_node!(graph, make_node(ComputeTaskS2()), false) + + ED = insert_node!(graph, make_node(DataTask(3)), false) + FD = insert_node!(graph, make_node(DataTask(3)), false) + + EC = insert_node!(graph, make_node(ComputeTaskV()), false) + FC = insert_node!(graph, make_node(ComputeTaskV()), false) + + A1D = insert_node!(graph, make_node(DataTask(4)), false) + B1D_1 = insert_node!(graph, make_node(DataTask(4)), false) + B1D_2 = insert_node!(graph, make_node(DataTask(4)), false) + C1D = insert_node!(graph, make_node(DataTask(4)), false) + + A1C = insert_node!(graph, make_node(ComputeTaskU()), false) + B1C_1 = insert_node!(graph, make_node(ComputeTaskU()), false) + B1C_2 = insert_node!(graph, make_node(ComputeTaskU()), false) + C1C = insert_node!(graph, make_node(ComputeTaskU()), false) + + AD = insert_node!(graph, make_node(DataTask(5)), false) + BD = insert_node!(graph, make_node(DataTask(5)), false) + CD = insert_node!(graph, make_node(DataTask(5)), false) + + insert_edge!(graph, make_edge(s0, d_exit), false) + insert_edge!(graph, make_edge(ED, s0), false) + insert_edge!(graph, make_edge(FD, s0), false) + insert_edge!(graph, make_edge(EC, ED), false) + insert_edge!(graph, make_edge(FC, FD), false) + + insert_edge!(graph, make_edge(A1D, EC), false) + insert_edge!(graph, make_edge(B1D_1, EC), false) + + insert_edge!(graph, make_edge(B1D_2, FC), false) + insert_edge!(graph, make_edge(C1D, FC), false) + + insert_edge!(graph, make_edge(A1C, A1D), false) + insert_edge!(graph, make_edge(B1C_1, B1D_1), false) + insert_edge!(graph, make_edge(B1C_2, B1D_2), false) + insert_edge!(graph, make_edge(C1C, C1D), false) + + insert_edge!(graph, make_edge(AD, A1C), false) + insert_edge!(graph, make_edge(BD, B1C_1), false) + insert_edge!(graph, make_edge(BD, B1C_2), false) + insert_edge!(graph, make_edge(CD, C1C), false) + + @test is_exit_node(d_exit) + @test is_entry_node(AD) + @test is_entry_node(BD) + @test is_entry_node(CD) + + opt = get_operations(graph) + + @test length(opt) == (nodeFusions = 6, nodeReductions = 1, nodeSplits = 1) + + println("Initial State:\n", opt) + + nr = first(opt.nodeReductions) + @test Set(nr.input) == Set([B1C_1, B1C_2]) + push_operation!(graph, nr) + opt = get_operations(graph) + + @test length(opt) == (nodeFusions = 4, nodeReductions = 1, nodeSplits = 1) + println("After 1 Node Reduction:\n", opt) + + nr = first(opt.nodeReductions) + @test Set(nr.input) == Set([B1D_1, B1D_2]) + push_operation!(graph, nr) + opt = get_operations(graph) + + @test length(opt) == (nodeFusions = 4, nodeReductions = 0, nodeSplits = 1) + println("After 2 Node Reductions:\n", opt) + + pop_operation!(graph) + + opt = get_operations(graph) + @test length(opt) == (nodeFusions = 4, nodeReductions = 1, nodeSplits = 1) + println("After reverting the second Node Reduction:\n", opt) + + reset_graph!(graph) + + opt = get_operations(graph) + @test length(opt) == (nodeFusions = 6, nodeReductions = 1, nodeSplits = 1) + println("After reverting to the initial state:\n", opt) +end +println("Node Reduction Unit Tests Complete!") diff --git a/test/runtests.jl b/test/runtests.jl index 50a707c..74f7f81 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,10 +2,11 @@ using MetagraphOptimization using Test @testset "MetagraphOptimization Tests" begin - include("unit_tests_utility.jl") - include("unit_tests_tasks.jl") - include("unit_tests_nodes.jl") - include("unit_tests_graph.jl") + include("unit_tests_utility.jl") + include("unit_tests_tasks.jl") + include("unit_tests_nodes.jl") + include("node_reduction.jl") + include("unit_tests_graph.jl") - include("known_graphs.jl") + include("known_graphs.jl") end diff --git a/test/unit_tests_graph.jl b/test/unit_tests_graph.jl index 85c9d0e..db166c5 100644 --- a/test/unit_tests_graph.jl +++ b/test/unit_tests_graph.jl @@ -6,205 +6,204 @@ import MetagraphOptimization.siblings import MetagraphOptimization.partners @testset "Unit Tests Graph" begin - graph = MetagraphOptimization.DAG() + graph = MetagraphOptimization.DAG() - @test length(graph.nodes) == 0 - @test length(graph.appliedOperations) == 0 - @test length(graph.operationsToApply) == 0 - @test length(graph.dirtyNodes) == 0 - @test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0) - @test length(get_operations(graph)) == (nodeFusions = 0, nodeReductions = 0, nodeSplits = 0) + @test length(graph.nodes) == 0 + @test length(graph.appliedOperations) == 0 + @test length(graph.operationsToApply) == 0 + @test length(graph.dirtyNodes) == 0 + @test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0) + @test length(get_operations(graph)) == (nodeFusions = 0, nodeReductions = 0, nodeSplits = 0) - # s to output (exit node) - d_exit = insert_node!(graph, make_node(DataTask(10)), false) + # s to output (exit node) + d_exit = insert_node!(graph, make_node(DataTask(10)), false) - @test length(graph.nodes) == 1 - @test length(graph.dirtyNodes) == 1 + @test length(graph.nodes) == 1 + @test length(graph.dirtyNodes) == 1 - # final s compute - s0 = insert_node!(graph, make_node(ComputeTaskS2()), false) + # final s compute + s0 = insert_node!(graph, make_node(ComputeTaskS2()), false) - @test length(graph.nodes) == 2 - @test length(graph.dirtyNodes) == 2 + @test length(graph.nodes) == 2 + @test length(graph.dirtyNodes) == 2 - # data from v0 and v1 to s0 - d_v0_s0 = insert_node!(graph, make_node(DataTask(5)), false) - d_v1_s0 = insert_node!(graph, make_node(DataTask(5)), false) + # data from v0 and v1 to s0 + d_v0_s0 = insert_node!(graph, make_node(DataTask(5)), false) + d_v1_s0 = insert_node!(graph, make_node(DataTask(5)), false) - # v0 and v1 compute - v0 = insert_node!(graph, make_node(ComputeTaskV()), false) - v1 = insert_node!(graph, make_node(ComputeTaskV()), false) + # v0 and v1 compute + v0 = insert_node!(graph, make_node(ComputeTaskV()), false) + v1 = insert_node!(graph, make_node(ComputeTaskV()), false) - # data from uB, uA, uBp and uAp to v0 and v1 - d_uB_v0 = insert_node!(graph, make_node(DataTask(3)), false) - d_uA_v0 = insert_node!(graph, make_node(DataTask(3)), false) - d_uBp_v1 = insert_node!(graph, make_node(DataTask(3)), false) - d_uAp_v1 = insert_node!(graph, make_node(DataTask(3)), false) + # data from uB, uA, uBp and uAp to v0 and v1 + d_uB_v0 = insert_node!(graph, make_node(DataTask(3)), false) + d_uA_v0 = insert_node!(graph, make_node(DataTask(3)), false) + d_uBp_v1 = insert_node!(graph, make_node(DataTask(3)), false) + d_uAp_v1 = insert_node!(graph, make_node(DataTask(3)), false) - # uB, uA, uBp and uAp computes - uB = insert_node!(graph, make_node(ComputeTaskU()), false) - uA = insert_node!(graph, make_node(ComputeTaskU()), false) - uBp = insert_node!(graph, make_node(ComputeTaskU()), false) - uAp = insert_node!(graph, make_node(ComputeTaskU()), false) + # uB, uA, uBp and uAp computes + uB = insert_node!(graph, make_node(ComputeTaskU()), false) + uA = insert_node!(graph, make_node(ComputeTaskU()), false) + uBp = insert_node!(graph, make_node(ComputeTaskU()), false) + uAp = insert_node!(graph, make_node(ComputeTaskU()), false) - # data from PB, PA, PBp and PAp to uB, uA, uBp and uAp - d_PB_uB = insert_node!(graph, make_node(DataTask(6)), false) - d_PA_uA = insert_node!(graph, make_node(DataTask(6)), false) - d_PBp_uBp = insert_node!(graph, make_node(DataTask(6)), false) - d_PAp_uAp = insert_node!(graph, make_node(DataTask(6)), false) + # data from PB, PA, PBp and PAp to uB, uA, uBp and uAp + d_PB_uB = insert_node!(graph, make_node(DataTask(6)), false) + d_PA_uA = insert_node!(graph, make_node(DataTask(6)), false) + d_PBp_uBp = insert_node!(graph, make_node(DataTask(6)), false) + d_PAp_uAp = insert_node!(graph, make_node(DataTask(6)), false) - # P computes PB, PA, PBp and PAp - PB = insert_node!(graph, make_node(ComputeTaskP()), false) - PA = insert_node!(graph, make_node(ComputeTaskP()), false) - PBp = insert_node!(graph, make_node(ComputeTaskP()), false) - PAp = insert_node!(graph, make_node(ComputeTaskP()), false) + # P computes PB, PA, PBp and PAp + PB = insert_node!(graph, make_node(ComputeTaskP()), false) + PA = insert_node!(graph, make_node(ComputeTaskP()), false) + PBp = insert_node!(graph, make_node(ComputeTaskP()), false) + PAp = insert_node!(graph, make_node(ComputeTaskP()), false) - # entry nodes getting data for P computes - d_PB = insert_node!(graph, make_node(DataTask(4)), false) - d_PA = insert_node!(graph, make_node(DataTask(4)), false) - d_PBp = insert_node!(graph, make_node(DataTask(4)), false) - d_PAp = insert_node!(graph, make_node(DataTask(4)), false) + # entry nodes getting data for P computes + d_PB = insert_node!(graph, make_node(DataTask(4)), false) + d_PA = insert_node!(graph, make_node(DataTask(4)), false) + d_PBp = insert_node!(graph, make_node(DataTask(4)), false) + d_PAp = insert_node!(graph, make_node(DataTask(4)), false) - @test length(graph.nodes) == 26 - @test length(graph.dirtyNodes) == 26 + @test length(graph.nodes) == 26 + @test length(graph.dirtyNodes) == 26 - # now for all the edgese - insert_edge!(graph, make_edge(d_PB, PB), false) - insert_edge!(graph, make_edge(d_PA, PA), false) - insert_edge!(graph, make_edge(d_PBp, PBp), false) - insert_edge!(graph, make_edge(d_PAp, PAp), false) + # now for all the edgese + insert_edge!(graph, make_edge(d_PB, PB), false) + insert_edge!(graph, make_edge(d_PA, PA), false) + insert_edge!(graph, make_edge(d_PBp, PBp), false) + insert_edge!(graph, make_edge(d_PAp, PAp), false) - insert_edge!(graph, make_edge(PB, d_PB_uB), false) - insert_edge!(graph, make_edge(PA, d_PA_uA), false) - insert_edge!(graph, make_edge(PBp, d_PBp_uBp), false) - insert_edge!(graph, make_edge(PAp, d_PAp_uAp), false) - - insert_edge!(graph, make_edge(d_PB_uB, uB), false) - insert_edge!(graph, make_edge(d_PA_uA, uA), false) - insert_edge!(graph, make_edge(d_PBp_uBp, uBp), false) - insert_edge!(graph, make_edge(d_PAp_uAp, uAp), false) + insert_edge!(graph, make_edge(PB, d_PB_uB), false) + insert_edge!(graph, make_edge(PA, d_PA_uA), false) + insert_edge!(graph, make_edge(PBp, d_PBp_uBp), false) + insert_edge!(graph, make_edge(PAp, d_PAp_uAp), false) - insert_edge!(graph, make_edge(uB, d_uB_v0), false) - insert_edge!(graph, make_edge(uA, d_uA_v0), false) - insert_edge!(graph, make_edge(uBp, d_uBp_v1), false) - insert_edge!(graph, make_edge(uAp, d_uAp_v1), false) + insert_edge!(graph, make_edge(d_PB_uB, uB), false) + insert_edge!(graph, make_edge(d_PA_uA, uA), false) + insert_edge!(graph, make_edge(d_PBp_uBp, uBp), false) + insert_edge!(graph, make_edge(d_PAp_uAp, uAp), false) - insert_edge!(graph, make_edge(d_uB_v0, v0), false) - insert_edge!(graph, make_edge(d_uA_v0, v0), false) - insert_edge!(graph, make_edge(d_uBp_v1, v1), false) - insert_edge!(graph, make_edge(d_uAp_v1, v1), false) + insert_edge!(graph, make_edge(uB, d_uB_v0), false) + insert_edge!(graph, make_edge(uA, d_uA_v0), false) + insert_edge!(graph, make_edge(uBp, d_uBp_v1), false) + insert_edge!(graph, make_edge(uAp, d_uAp_v1), false) - insert_edge!(graph, make_edge(v0, d_v0_s0), false) - insert_edge!(graph, make_edge(v1, d_v1_s0), false) + insert_edge!(graph, make_edge(d_uB_v0, v0), false) + insert_edge!(graph, make_edge(d_uA_v0, v0), false) + insert_edge!(graph, make_edge(d_uBp_v1, v1), false) + insert_edge!(graph, make_edge(d_uAp_v1, v1), false) - insert_edge!(graph, make_edge(d_v0_s0, s0), false) - insert_edge!(graph, make_edge(d_v1_s0, s0), false) + insert_edge!(graph, make_edge(v0, d_v0_s0), false) + insert_edge!(graph, make_edge(v1, d_v1_s0), false) - insert_edge!(graph, make_edge(s0, d_exit), false) + insert_edge!(graph, make_edge(d_v0_s0, s0), false) + insert_edge!(graph, make_edge(d_v1_s0, s0), false) - @test length(graph.nodes) == 26 - @test length(graph.appliedOperations) == 0 - @test length(graph.operationsToApply) == 0 - @test length(graph.dirtyNodes) == 26 - @test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0) + insert_edge!(graph, make_edge(s0, d_exit), false) - @test is_entry_node(d_PB) - @test is_entry_node(d_PA) - @test is_entry_node(d_PBp) - @test is_entry_node(d_PBp) - @test !is_entry_node(PB) - @test !is_entry_node(v0) - @test !is_entry_node(d_exit) + @test length(graph.nodes) == 26 + @test length(graph.appliedOperations) == 0 + @test length(graph.operationsToApply) == 0 + @test length(graph.dirtyNodes) == 26 + @test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0) - @test is_exit_node(d_exit) - @test !is_exit_node(d_uB_v0) - @test !is_exit_node(v0) - - @test length(children(v0)) == 2 - @test length(children(v1)) == 2 - @test length(parents(v0)) == 1 - @test length(parents(v1)) == 1 + @test is_entry_node(d_PB) + @test is_entry_node(d_PA) + @test is_entry_node(d_PBp) + @test is_entry_node(d_PBp) + @test !is_entry_node(PB) + @test !is_entry_node(v0) + @test !is_entry_node(d_exit) - @test MetagraphOptimization.get_exit_node(graph) == d_exit + @test is_exit_node(d_exit) + @test !is_exit_node(d_uB_v0) + @test !is_exit_node(v0) - @test length(partners(s0)) == 1 - @test length(siblings(s0)) == 1 + @test length(children(v0)) == 2 + @test length(children(v1)) == 2 + @test length(parents(v0)) == 1 + @test length(parents(v1)) == 1 - operations = get_operations(graph) - @test length(operations) == (nodeFusions = 10, nodeReductions = 0, nodeSplits = 0) - @test length(graph.dirtyNodes) == 0 + @test MetagraphOptimization.get_exit_node(graph) == d_exit - @test operations == get_operations(graph) - nf = first(operations.nodeFusions) + @test length(partners(s0)) == 1 + @test length(siblings(s0)) == 1 - properties = graph_properties(graph) - @test properties.compute_effort == 134 - @test properties.data == 62 - @test properties.compute_intensity ≈ 134/62 - @test properties.nodes == 26 - @test properties.edges == 25 + operations = get_operations(graph) + @test length(operations) == (nodeFusions = 10, nodeReductions = 0, nodeSplits = 0) + @test length(graph.dirtyNodes) == 0 - push_operation!(graph, nf) - # **does not immediately apply the operation** + @test operations == get_operations(graph) + nf = first(operations.nodeFusions) - @test length(graph.nodes) == 26 - @test length(graph.appliedOperations) == 0 - @test length(graph.operationsToApply) == 1 - @test first(graph.operationsToApply) == nf - @test length(graph.dirtyNodes) == 0 - @test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0) + properties = graph_properties(graph) + @test properties.compute_effort == 134 + @test properties.data == 62 + @test properties.compute_intensity ≈ 134/62 + @test properties.nodes == 26 + @test properties.edges == 25 - # this applies pending operations - properties = graph_properties(graph) + push_operation!(graph, nf) + # **does not immediately apply the operation** - @test length(graph.nodes) == 24 - @test length(graph.appliedOperations) == 1 - @test length(graph.operationsToApply) == 0 - @test length(graph.dirtyNodes) != 0 - @test properties.nodes == 24 - @test properties.edges == 23 - @test properties.compute_effort == 134 - @test properties.data < 62 - @test properties.compute_intensity > 134/62 + @test length(graph.nodes) == 26 + @test length(graph.appliedOperations) == 0 + @test length(graph.operationsToApply) == 1 + @test first(graph.operationsToApply) == nf + @test length(graph.dirtyNodes) == 0 + @test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0) - operations = get_operations(graph) - @test length(graph.dirtyNodes) == 0 - - @test length(operations) == (nodeFusions = 9, nodeReductions = 0, nodeSplits = 0) - @test !isempty(operations) + # this applies pending operations + properties = graph_properties(graph) - possibleNF = 9 - while !isempty(operations.nodeFusions) - push_operation!(graph, first(operations.nodeFusions)) - operations = get_operations(graph) - possibleNF = possibleNF - 1 - @test length(operations) == (nodeFusions = possibleNF, nodeReductions = 0, nodeSplits = 0) - end + @test length(graph.nodes) == 24 + @test length(graph.appliedOperations) == 1 + @test length(graph.operationsToApply) == 0 + @test length(graph.dirtyNodes) != 0 + @test properties.nodes == 24 + @test properties.edges == 23 + @test properties.compute_effort == 134 + @test properties.data < 62 + @test properties.compute_intensity > 134/62 - @test isempty(operations) + operations = get_operations(graph) + @test length(graph.dirtyNodes) == 0 - @test length(operations) == (nodeFusions = 0, nodeReductions = 0, nodeSplits = 0) - @test length(graph.dirtyNodes) == 0 - @test length(graph.nodes) == 6 - @test length(graph.appliedOperations) == 10 - @test length(graph.operationsToApply) == 0 + @test length(operations) == (nodeFusions = 9, nodeReductions = 0, nodeSplits = 0) + @test !isempty(operations) - reset_graph!(graph) + possibleNF = 9 + while !isempty(operations.nodeFusions) + push_operation!(graph, first(operations.nodeFusions)) + operations = get_operations(graph) + possibleNF = possibleNF - 1 + @test length(operations) == (nodeFusions = possibleNF, nodeReductions = 0, nodeSplits = 0) + end - @test length(graph.dirtyNodes) == 26 - @test length(graph.nodes) == 26 - @test length(graph.appliedOperations) == 0 - @test length(graph.operationsToApply) == 0 + @test isempty(operations) - properties = graph_properties(graph) - @test properties.nodes == 26 - @test properties.edges == 25 - @test properties.compute_effort == 134 - @test properties.data == 62 - @test properties.compute_intensity ≈ 134/62 + @test length(operations) == (nodeFusions = 0, nodeReductions = 0, nodeSplits = 0) + @test length(graph.dirtyNodes) == 0 + @test length(graph.nodes) == 6 + @test length(graph.appliedOperations) == 10 + @test length(graph.operationsToApply) == 0 - operations = get_operations(graph) - @test length(operations) == (nodeFusions = 10, nodeReductions = 0, nodeSplits = 0) + reset_graph!(graph) + @test length(graph.dirtyNodes) == 26 + @test length(graph.nodes) == 26 + @test length(graph.appliedOperations) == 0 + @test length(graph.operationsToApply) == 0 + + properties = graph_properties(graph) + @test properties.nodes == 26 + @test properties.edges == 25 + @test properties.compute_effort == 134 + @test properties.data == 62 + @test properties.compute_intensity ≈ 134/62 + + operations = get_operations(graph) + @test length(operations) == (nodeFusions = 10, nodeReductions = 0, nodeSplits = 0) end println("Graph Unit Tests Complete!") diff --git a/test/unit_tests_nodes.jl b/test/unit_tests_nodes.jl index 6a696d6..7a274d0 100644 --- a/test/unit_tests_nodes.jl +++ b/test/unit_tests_nodes.jl @@ -1,36 +1,36 @@ @testset "Unit Tests Nodes" begin - nC1 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskU()) - nC2 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskV()) - nC3 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskP()) - nC4 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskSum()) + nC1 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskU()) + nC2 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskV()) + nC3 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskP()) + nC4 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskSum()) - nD1 = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(10)) - nD2 = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(20)) + nD1 = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(10)) + nD2 = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(20)) - @test_throws ErrorException MetagraphOptimization.make_edge(nC1, nC2) - @test_throws ErrorException MetagraphOptimization.make_edge(nC1, nC1) - @test_throws ErrorException MetagraphOptimization.make_edge(nC3, nC4) - @test_throws ErrorException MetagraphOptimization.make_edge(nD1, nD2) - @test_throws ErrorException MetagraphOptimization.make_edge(nD1, nD1) + @test_throws ErrorException MetagraphOptimization.make_edge(nC1, nC2) + @test_throws ErrorException MetagraphOptimization.make_edge(nC1, nC1) + @test_throws ErrorException MetagraphOptimization.make_edge(nC3, nC4) + @test_throws ErrorException MetagraphOptimization.make_edge(nD1, nD2) + @test_throws ErrorException MetagraphOptimization.make_edge(nD1, nD1) - ed1 = MetagraphOptimization.make_edge(nC1, nD1) - ed2 = MetagraphOptimization.make_edge(nD1, nC2) - ed3 = MetagraphOptimization.make_edge(nC2, nD2) - ed4 = MetagraphOptimization.make_edge(nD2, nC3) + ed1 = MetagraphOptimization.make_edge(nC1, nD1) + ed2 = MetagraphOptimization.make_edge(nD1, nC2) + ed3 = MetagraphOptimization.make_edge(nC2, nD2) + ed4 = MetagraphOptimization.make_edge(nD2, nC3) - @test nC1 != nC2 - @test nD1 != nD2 - @test nC1 != nD1 - @test nC3 != nC4 + @test nC1 != nC2 + @test nD1 != nD2 + @test nC1 != nD1 + @test nC3 != nC4 - nC1_2 = copy(nC1) - @test nC1_2 != nC1 - - nD1_2 = copy(nD1) - @test nD1_2 != nD1 + nC1_2 = copy(nC1) + @test nC1_2 != nC1 - nD1_c = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(10)) - @test nD1_c != nD1 + nD1_2 = copy(nD1) + @test nD1_2 != nD1 + + nD1_c = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(10)) + @test nD1_c != nD1 end println("Node Unit Tests Complete!") diff --git a/test/unit_tests_tasks.jl b/test/unit_tests_tasks.jl index 3737865..b4d6c96 100644 --- a/test/unit_tests_tasks.jl +++ b/test/unit_tests_tasks.jl @@ -1,60 +1,60 @@ @testset "Task Unit Tests" begin - S1 = MetagraphOptimization.ComputeTaskS1() - S2 = MetagraphOptimization.ComputeTaskS2() - U = MetagraphOptimization.ComputeTaskU() - V = MetagraphOptimization.ComputeTaskV() - P = MetagraphOptimization.ComputeTaskP() - Sum = MetagraphOptimization.ComputeTaskSum() + S1 = MetagraphOptimization.ComputeTaskS1() + S2 = MetagraphOptimization.ComputeTaskS2() + U = MetagraphOptimization.ComputeTaskU() + V = MetagraphOptimization.ComputeTaskV() + P = MetagraphOptimization.ComputeTaskP() + Sum = MetagraphOptimization.ComputeTaskSum() - Data10 = MetagraphOptimization.DataTask(10) - Data20 = MetagraphOptimization.DataTask(20) + Data10 = MetagraphOptimization.DataTask(10) + Data20 = MetagraphOptimization.DataTask(20) - @test MetagraphOptimization.compute_effort(S1) == 10 - @test MetagraphOptimization.compute_effort(S2) == 10 - @test MetagraphOptimization.compute_effort(U) == 6 - @test MetagraphOptimization.compute_effort(V) == 20 - @test MetagraphOptimization.compute_effort(P) == 15 - @test MetagraphOptimization.compute_effort(Sum) == 1 - @test MetagraphOptimization.compute_effort(Data10) == 0 - @test MetagraphOptimization.compute_effort(Data20) == 0 + @test MetagraphOptimization.compute_effort(S1) == 10 + @test MetagraphOptimization.compute_effort(S2) == 10 + @test MetagraphOptimization.compute_effort(U) == 6 + @test MetagraphOptimization.compute_effort(V) == 20 + @test MetagraphOptimization.compute_effort(P) == 15 + @test MetagraphOptimization.compute_effort(Sum) == 1 + @test MetagraphOptimization.compute_effort(Data10) == 0 + @test MetagraphOptimization.compute_effort(Data20) == 0 - @test MetagraphOptimization.data(S1) == 0 - @test MetagraphOptimization.data(S2) == 0 - @test MetagraphOptimization.data(U) == 0 - @test MetagraphOptimization.data(V) == 0 - @test MetagraphOptimization.data(P) == 0 - @test MetagraphOptimization.data(Sum) == 0 - @test MetagraphOptimization.data(Data10) == 10 - @test MetagraphOptimization.data(Data20) == 20 + @test MetagraphOptimization.data(S1) == 0 + @test MetagraphOptimization.data(S2) == 0 + @test MetagraphOptimization.data(U) == 0 + @test MetagraphOptimization.data(V) == 0 + @test MetagraphOptimization.data(P) == 0 + @test MetagraphOptimization.data(Sum) == 0 + @test MetagraphOptimization.data(Data10) == 10 + @test MetagraphOptimization.data(Data20) == 20 - @test MetagraphOptimization.compute_intensity(S1) == typemax(UInt64) - @test MetagraphOptimization.compute_intensity(S2) == typemax(UInt64) - @test MetagraphOptimization.compute_intensity(U) == typemax(UInt64) - @test MetagraphOptimization.compute_intensity(V) == typemax(UInt64) - @test MetagraphOptimization.compute_intensity(P) == typemax(UInt64) - @test MetagraphOptimization.compute_intensity(Sum) == typemax(UInt64) - @test MetagraphOptimization.compute_intensity(Data10) == 0 - @test MetagraphOptimization.compute_intensity(Data20) == 0 + @test MetagraphOptimization.compute_intensity(S1) == typemax(UInt64) + @test MetagraphOptimization.compute_intensity(S2) == typemax(UInt64) + @test MetagraphOptimization.compute_intensity(U) == typemax(UInt64) + @test MetagraphOptimization.compute_intensity(V) == typemax(UInt64) + @test MetagraphOptimization.compute_intensity(P) == typemax(UInt64) + @test MetagraphOptimization.compute_intensity(Sum) == typemax(UInt64) + @test MetagraphOptimization.compute_intensity(Data10) == 0 + @test MetagraphOptimization.compute_intensity(Data20) == 0 - @test S1 != S2 - @test Data10 != Data20 - - Data10_2 = MetagraphOptimization.DataTask(10) + @test S1 != S2 + @test Data10 != Data20 - # two data tasks with same data are identical, their nodes need not be - @test Data10_2 == Data10 + Data10_2 = MetagraphOptimization.DataTask(10) - @test Data10 == Data10 - @test S1 == S1 + # two data tasks with same data are identical, their nodes need not be + @test Data10_2 == Data10 - Data10_3 = copy(Data10) + @test Data10 == Data10 + @test S1 == S1 - @test Data10_3 == Data10 + Data10_3 = copy(Data10) - S1_2 = copy(S1) + @test Data10_3 == Data10 - @test S1_2 == S1 - @test S1 == MetagraphOptimization.ComputeTaskS1() + S1_2 = copy(S1) + + @test S1_2 == S1 + @test S1 == MetagraphOptimization.ComputeTaskS1() end println("Task Unit Tests Complete!") diff --git a/test/unit_tests_utility.jl b/test/unit_tests_utility.jl index cd989ce..db04d80 100644 --- a/test/unit_tests_utility.jl +++ b/test/unit_tests_utility.jl @@ -1,11 +1,11 @@ @testset "Unit Tests Utility" begin - @test MetagraphOptimization.bytes_to_human_readable(0) == "0.0 B" - @test MetagraphOptimization.bytes_to_human_readable(1020) == "1020.0 B" - @test MetagraphOptimization.bytes_to_human_readable(1025) == "1.001 KiB" - @test MetagraphOptimization.bytes_to_human_readable(684235) == "668.2 KiB" - @test MetagraphOptimization.bytes_to_human_readable(86214576) == "82.22 MiB" - @test MetagraphOptimization.bytes_to_human_readable(9241457698) == "8.607 GiB" - @test MetagraphOptimization.bytes_to_human_readable(3218598654367) == "2.927 TiB" + @test MetagraphOptimization.bytes_to_human_readable(0) == "0.0 B" + @test MetagraphOptimization.bytes_to_human_readable(1020) == "1020.0 B" + @test MetagraphOptimization.bytes_to_human_readable(1025) == "1.001 KiB" + @test MetagraphOptimization.bytes_to_human_readable(684235) == "668.2 KiB" + @test MetagraphOptimization.bytes_to_human_readable(86214576) == "82.22 MiB" + @test MetagraphOptimization.bytes_to_human_readable(9241457698) == "8.607 GiB" + @test MetagraphOptimization.bytes_to_human_readable(3218598654367) == "2.927 TiB" end println("Utility Unit Tests Complete!")