From 7cc521167e204eeda8071b94f7d78a4ed5a51744 Mon Sep 17 00:00:00 2001 From: Natacha Javerzat Date: Tue, 23 May 2023 12:04:19 +0200 Subject: [PATCH 1/4] init Coluna profiling --- test/perf/generalized_assigment.jl | 66 ++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 test/perf/generalized_assigment.jl diff --git a/test/perf/generalized_assigment.jl b/test/perf/generalized_assigment.jl new file mode 100644 index 000000000..0fccfc377 --- /dev/null +++ b/test/perf/generalized_assigment.jl @@ -0,0 +1,66 @@ +using Profile, PProf +using Coluna + +using GLPK, ColunaDemos, JuMP, BlockDecomposition + +function gap_toy_instance() + data = ColunaDemos.GeneralizedAssignment.data("play2.txt") + + coluna = JuMP.optimizer_with_attributes( + Coluna.Optimizer, + "params" => Coluna.Params(solver = Coluna.Algorithm.BranchCutAndPriceAlgorithm( + branchingtreefile = "playgap.dot" + )), + "default_optimizer" => GLPK.Optimizer + ) + + model, x, dec = ColunaDemos.GeneralizedAssignment.model(data, coluna) + BlockDecomposition.objectiveprimalbound!(model, 100) + BlockDecomposition.objectivedualbound!(model, 0) + + JuMP.optimize!(model) +end + + +function gap_strong_branching() + println("\e[45m gap strong branching \e[00m") + data = ColunaDemos.GeneralizedAssignment.data("mediumgapcuts3.txt") + + coluna = JuMP.optimizer_with_attributes( + Coluna.Optimizer, + "params" => Coluna.Params( + solver = Coluna.Algorithm.BranchCutAndPriceAlgorithm( + maxnumnodes = 300, + colgen_stabilization = 1.0, + colgen_cleanup_threshold = 150, + stbranch_phases_num_candidates = [10, 3, 1], + stbranch_intrmphase_stages = [(userstage=1, solverid=1, maxiters=2)] + ) + ), + "default_optimizer" => GLPK.Optimizer + ) + + model, x, dec = ColunaDemos.GeneralizedAssignment.model(data, coluna) + + # we increase the branching priority of variables which assign jobs to the first two machines + for machine in 1:2 + for job in data.jobs + BlockDecomposition.branchingpriority!(x[machine,job], 2) + end + end + + BlockDecomposition.objectiveprimalbound!(model, 2000.0) + BlockDecomposition.objectivedualbound!(model, 0.0) + + JuMP.optimize!(model) +end + + +gap_toy_instance() +gap_strong_branching() + +Profile.clear() +@profile gap_toy_instance() +@profile gap_strong_branching() +pprof() +readline() \ No newline at end of file From 53944eb531e4b5dac6c36798d60758c904bbc69c Mon Sep 17 00:00:00 2001 From: Natacha Javerzat Date: Wed, 24 May 2023 11:53:17 +0200 Subject: [PATCH 2/4] add bigger instance, refine profiling --- test/perf/generalized_assigment.jl | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/test/perf/generalized_assigment.jl b/test/perf/generalized_assigment.jl index 0fccfc377..73d150751 100644 --- a/test/perf/generalized_assigment.jl +++ b/test/perf/generalized_assigment.jl @@ -55,12 +55,33 @@ function gap_strong_branching() JuMP.optimize!(model) end +function gap_big_instance() + data = ColunaDemos.GeneralizedAssignment.data("gapC-5-100.txt") -gap_toy_instance() + coluna = JuMP.optimizer_with_attributes( + Coluna.Optimizer, + "params" => Coluna.Params(solver = Coluna.Algorithm.BranchCutAndPriceAlgorithm( + ) + ), + "default_optimizer" => GLPK.Optimizer + ) + + model, x, dec = ColunaDemos.GeneralizedAssignment.model(data, coluna) + #BlockDecomposition.objectiveprimalbound!(model, 100) + #BlockDecomposition.objectivedualbound!(model, 0) + + JuMP.optimize!(model) +end + + +#gap_toy_instance() gap_strong_branching() +#gap_big_instance() Profile.clear() -@profile gap_toy_instance() +Profile.init(; n = 10^6, delay = 0.005) +#@profile gap_toy_instance() @profile gap_strong_branching() +#@profile gap_big_instance() pprof() readline() \ No newline at end of file From a7143bb930bde02588bd16e1c98d15a14b735221 Mon Sep 17 00:00:00 2001 From: Natacha Javerzat Date: Thu, 25 May 2023 14:10:02 +0200 Subject: [PATCH 3/4] add instance mediumgapcuts1 --- test/perf/generalized_assigment.jl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/perf/generalized_assigment.jl b/test/perf/generalized_assigment.jl index 73d150751..b3e76ac61 100644 --- a/test/perf/generalized_assigment.jl +++ b/test/perf/generalized_assigment.jl @@ -56,11 +56,12 @@ function gap_strong_branching() end function gap_big_instance() - data = ColunaDemos.GeneralizedAssignment.data("gapC-5-100.txt") + data = ColunaDemos.GeneralizedAssignment.data("mediumgapcuts1.txt") coluna = JuMP.optimizer_with_attributes( Coluna.Optimizer, "params" => Coluna.Params(solver = Coluna.Algorithm.BranchCutAndPriceAlgorithm( + maxnumnodes=5 ) ), "default_optimizer" => GLPK.Optimizer @@ -75,13 +76,13 @@ end #gap_toy_instance() -gap_strong_branching() -#gap_big_instance() +#gap_strong_branching() +gap_big_instance() Profile.clear() Profile.init(; n = 10^6, delay = 0.005) #@profile gap_toy_instance() -@profile gap_strong_branching() -#@profile gap_big_instance() +#@profile gap_strong_branching() +@profile gap_big_instance() pprof() readline() \ No newline at end of file From 9b694c81b55d014fe394da0e580b87c6ac0dac01 Mon Sep 17 00:00:00 2001 From: Natacha Javerzat Date: Thu, 25 May 2023 16:07:23 +0200 Subject: [PATCH 4/4] add alloc profile and glossary --- test/perf/generalized_assigment.jl | 9 +++++++- test/perf/glossary.md | 35 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/perf/glossary.md diff --git a/test/perf/generalized_assigment.jl b/test/perf/generalized_assigment.jl index b3e76ac61..c4f3f6362 100644 --- a/test/perf/generalized_assigment.jl +++ b/test/perf/generalized_assigment.jl @@ -85,4 +85,11 @@ Profile.init(; n = 10^6, delay = 0.005) #@profile gap_strong_branching() @profile gap_big_instance() pprof() -readline() \ No newline at end of file +readline() + +# Collect an allocation profile +#Profile.Allocs.@profile gap_big_instance() + +# Export pprof allocation profile and open interactive profiling web interface. +#PProf.Allocs.pprof() +#readline() \ No newline at end of file diff --git a/test/perf/glossary.md b/test/perf/glossary.md new file mode 100644 index 000000000..e5f7c45e3 --- /dev/null +++ b/test/perf/glossary.md @@ -0,0 +1,35 @@ +## Generate Julia code profile using ```PProf.jl``` + +https://github.com/JuliaPerf/PProf.jl + + + +## Interpret code profiling + +useful links: +https://docs.julialang.org/en/v1/devdocs/init/ +https://docs.julialang.org/en/v1/devdocs/ast/ +https://docs.julialang.org/en/v1/devdocs/functions/ + + +some Julia build-in methods: + +- ```jl_repl_entrypoint```: loads the contents of ```argv[ ]``` +- ```eval``` calls ```jl_toplevel_eval_in``` which calls ```jl_toplevel_eval_flex``` +- ```jl_toplevel_eval_flex``` implements a simple heuristic to decide whether to compile a given code thunk or run it by interpreter. +- ```jl_interpret_toplevel_thunk``` is called by ```jl_toplevel_eval_flex``` when deciding to run the code by interpreter. It then calls ```eval_body``` +- ```jl_apply_generic```: perfoms the dispatch process. +- ```kwcall```: "keyword argument sorter" or "keyword sorter", manages the keyword argurments when calling a method, e.g. consider method (see ```/devdocs/functions.md``` from Julia repo to get an example and more details) + + +how to read pprof output ? + +- graph: (taken from https://github.com/google/pprof/issues/493) + * Dotted/dashed lines indicated that that intervening nodes have been removed. Nodes are removed to keep graphs small enough for visualization. + * The wider an arrow the more of the metric being measured is used along that path. + * Nodes and edges are colored according to their total value (total being the amount of a metric used by a node and all of its children); large positive values are red; large negative values are green. + +- flat/cum: + + * flat: the value of the location itself. + * cum: the value of the location plus all its descendants.