diff --git a/test/perf/generalized_assigment.jl b/test/perf/generalized_assigment.jl new file mode 100644 index 000000000..c4f3f6362 --- /dev/null +++ b/test/perf/generalized_assigment.jl @@ -0,0 +1,95 @@ +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 + +function gap_big_instance() + 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 + ) + + 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.init(; n = 10^6, delay = 0.005) +#@profile gap_toy_instance() +#@profile gap_strong_branching() +@profile gap_big_instance() +pprof() +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.