Optimizer interface and sample implementation (#19)

Reviewed-on: Rubydragon/MetagraphOptimization.jl#19
Co-authored-by: Anton Reinhard <anton.reinhard@proton.me>
Co-committed-by: Anton Reinhard <anton.reinhard@proton.me>
This commit is contained in:
2023-11-22 13:51:54 +01:00
committed by Anton Reinhard
parent 16274919e4
commit b7560685d4
53 changed files with 639 additions and 331 deletions

View File

@ -11,6 +11,7 @@ using Test
include("node_reduction.jl")
include("unit_tests_graph.jl")
include("unit_tests_execution.jl")
include("unit_tests_optimization.jl")
include("known_graphs.jl")
end

View File

@ -38,9 +38,6 @@ function test_op_specific(estimator, graph, ns::NodeSplit)
end
function test_op(estimator, graph, op)
#=
See issue #16
estimate_before = graph_cost(estimator, graph)
estimate = operation_effect(estimator, graph, op)
@ -52,7 +49,6 @@ function test_op(estimator, graph, op)
@test isapprox((estimate_before + estimate).data, estimate_after_apply.data)
@test isapprox((estimate_before + estimate).computeEffort, estimate_after_apply.computeEffort)
@test isapprox((estimate_before + estimate).computeIntensity, estimate_after_apply.computeIntensity)
=#
test_op_specific(estimator, graph, op)
return nothing
@ -81,9 +77,6 @@ end
nrs = copy(ops.nodeReductions)
nss = copy(ops.nodeSplits)
println(
"Testing $(length(ops.nodeFusions))xNF, $(length(ops.nodeReductions))xNR, $(length(ops.nodeSplits))xNS",
)
for nf in nfs
test_op(estimator, graph, nf)
end

View File

@ -3,10 +3,10 @@ import MetagraphOptimization.interaction_result
using QEDbase
using AccurateArithmetic
include("../examples/profiling_utilities.jl")
using Random
const RTOL = sqrt(eps(Float64))
RNG = Random.default_rng()
function check_particle_reverse_moment(p1::SFourMomentum, p2::SFourMomentum)
@test isapprox(abs(p1.E), abs(p2.E))
@ -83,7 +83,7 @@ end
@testset "AB->AB after random walk" begin
for i in 1:200
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->AB.txt"), ABCModel())
random_walk!(graph, 50)
optimize!(RandomWalkOptimizer(RNG), graph, 50)
@test is_valid(graph)
@ -115,7 +115,7 @@ end
@testset "AB->ABBB after random walk" begin
for i in 1:50
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->ABBB.txt"), ABCModel())
random_walk!(graph, 100)
optimize!(RandomWalkOptimizer(RNG), graph, 100)
@test is_valid(graph)
@test isapprox(execute(graph, process_2_4, machine, particles_2_4), expected_result; rtol = RTOL)

View File

@ -135,6 +135,12 @@ import MetagraphOptimization.partners
@test length(operations) == (nodeFusions = 10, nodeReductions = 0, nodeSplits = 0)
@test length(graph.dirtyNodes) == 0
i = 0
for op in operations
i += 1
end
@test i == 10
@test operations == get_operations(graph)
nf = first(operations.nodeFusions)

View File

@ -0,0 +1,42 @@
using Random
RNG = Random.default_rng()
@testset "Unit Tests Optimization" begin
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->ABBB.txt"), ABCModel())
# create the optimizers
FIXPOINT_OPTIMIZERS = [GreedyOptimizer(GlobalMetricEstimator()), ReductionOptimizer()]
NO_FIXPOINT_OPTIMIZERS = [RandomWalkOptimizer(RNG)]
@testset "Optimizer $optimizer" for optimizer in vcat(NO_FIXPOINT_OPTIMIZERS, FIXPOINT_OPTIMIZERS)
@test operation_stack_length(graph) == 0
@test optimize_step!(optimizer, graph)
@test !fixpoint_reached(optimizer, graph)
@test operation_stack_length(graph) == 1
@test optimize!(optimizer, graph, 10)
@test !fixpoint_reached(optimizer, graph)
reset_graph!(graph)
end
@testset "Fixpoint optimizer $optimizer" for optimizer in FIXPOINT_OPTIMIZERS
@test operation_stack_length(graph) == 0
optimize_to_fixpoint!(optimizer, graph)
@test fixpoint_reached(optimizer, graph)
@test !optimize_step!(optimizer, graph)
@test !optimize!(optimizer, graph, 10)
reset_graph!(graph)
end
@testset "No fixpoint optimizer $optimizer" for optimizer in NO_FIXPOINT_OPTIMIZERS
@test_throws MethodError optimize_to_fixpoint!(optimizer, graph)
end
end
println("Optimization Unit Tests Complete!")

View File

@ -5,18 +5,10 @@
@test prop.data == 0.0
@test prop.computeEffort == 0.0
@test prop.computeIntensity == 0.0
@test prop.cost == 0.0
@test prop.noNodes == 0.0
@test prop.noEdges == 0.0
prop2 = (
data = 5.0,
computeEffort = 6.0,
computeIntensity = 6.0 / 5.0,
cost = 0.0,
noNodes = 2,
noEdges = 3,
)::GraphProperties
prop2 = (data = 5.0, computeEffort = 6.0, computeIntensity = 6.0 / 5.0, noNodes = 2, noEdges = 3)::GraphProperties
@test prop + prop2 == prop2
@test prop2 - prop == prop2
@ -25,27 +17,18 @@
@test negProp.data == -5.0
@test negProp.computeEffort == -6.0
@test negProp.computeIntensity == 6.0 / 5.0
@test negProp.cost == 0.0
@test negProp.noNodes == -2
@test negProp.noEdges == -3
@test negProp + prop2 == GraphProperties()
prop3 = (
data = 7.0,
computeEffort = 3.0,
computeIntensity = 7.0 / 3.0,
cost = 0.0,
noNodes = -3,
noEdges = 2,
)::GraphProperties
prop3 = (data = 7.0, computeEffort = 3.0, computeIntensity = 7.0 / 3.0, noNodes = -3, noEdges = 2)::GraphProperties
propSum = prop2 + prop3
@test propSum.data == 12.0
@test propSum.computeEffort == 9.0
@test propSum.computeIntensity == 9.0 / 12.0
@test propSum.cost == 0.0
@test propSum.noNodes == -1
@test propSum.noEdges == 5
end