Skip to content

Commit

Permalink
Merge pull request #67 from daschw/precompile
Browse files Browse the repository at this point in the history
add CompileBot
  • Loading branch information
daschw authored Nov 9, 2020
2 parents d30b5f4 + 286d957 commit e33afb0
Show file tree
Hide file tree
Showing 14 changed files with 298 additions and 15 deletions.
88 changes: 88 additions & 0 deletions RecipesPipeline/.github/workflows/SnoopCompile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: SnoopCompile

on:
push:
branches:
# - 'master' # NOTE: to run the bot only on pushes to master

defaults:
run:
shell: bash

jobs:
SnoopCompile:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
env:
GKS_ENCODING: "utf8"

runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
version: # NOTE: the versions below should match those in your botconfig
- '1.5'
os: # NOTE: should match the os setting of your botconfig
- ubuntu-latest
arch:
- x64
steps:
# Setup environment
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@latest
with:
version: ${{ matrix.version }}

- name: Install dependencies
run: |
julia --project -e 'using Pkg; Pkg.instantiate();'
julia -e 'using Pkg; Pkg.add( PackageSpec(name = "CompileBot", version = "1") ); Pkg.develop(PackageSpec(; path=pwd())); using CompileBot; CompileBot.addtestdep();'
# TESTCMD
- name: Default TESTCMD
run: echo ::set-env name=TESTCMD::"julia"
- name: Ubuntu TESTCMD
if: startsWith(matrix.os,'ubuntu')
run: echo ::set-env name=TESTCMD::"xvfb-run --auto-servernum julia"

# Generate precompile files
- name: Generating precompile files
run: $TESTCMD --project -e 'include("deps/SnoopCompile/snoop_bot.jl")' # NOTE: must match path

# Run benchmarks
- name: Running Benchmark
run: $TESTCMD --project -e 'include("deps/SnoopCompile/snoop_bench.jl")' # NOTE: optional, if have benchmark file

- name: Upload all
uses: actions/[email protected]
with:
path: ./

Create_PR:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
needs: SnoopCompile
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Download all
uses: actions/download-artifact@v2

- name: CompileBot postprocess
run: julia -e 'using Pkg; Pkg.add( PackageSpec(name = "CompileBot", version = "1") ); using CompileBot; CompileBot.postprocess();'

- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Update precompile_*.jl file
title: "[AUTO] Update precompiles"
labels: SnoopCompile
branch: "SnoopCompile_AutoPR"


Skip:
if: "contains(github.event.head_commit.message, '[skip ci]')"
runs-on: ubuntu-latest
steps:
- name: Skip CI 🚫
run: echo skip ci
2 changes: 1 addition & 1 deletion RecipesPipeline/Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "RecipesPipeline"
uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c"
authors = ["Michael Krabbe Borregaard <[email protected]>"]
version = "0.1.13"
version = "0.2"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
const __bodyfunction__ = Dict{Method,Any}()

# Find keyword "body functions" (the function that contains the body
# as written by the developer, called after all missing keyword-arguments
# have been assigned values), in a manner that doesn't depend on
# gensymmed names.
# `mnokw` is the method that gets called when you invoke it without
# supplying any keywords.
function __lookup_kwbody__(mnokw::Method)
function getsym(arg)
isa(arg, Symbol) && return arg
@assert isa(arg, GlobalRef)
return arg.name
end

f = get(__bodyfunction__, mnokw, nothing)
if f === nothing
fmod = mnokw.module
# The lowered code for `mnokw` should look like
# %1 = mkw(kwvalues..., #self#, args...)
# return %1
# where `mkw` is the name of the "active" keyword body-function.
ast = Base.uncompressed_ast(mnokw)
if isa(ast, Core.CodeInfo) && length(ast.code) >= 2
callexpr = ast.code[end-1]
if isa(callexpr, Expr) && callexpr.head == :call
fsym = callexpr.args[1]
if isa(fsym, Symbol)
f = getfield(fmod, fsym)
elseif isa(fsym, GlobalRef)
if fsym.mod === Core && fsym.name === :_apply
f = getfield(mnokw.module, getsym(callexpr.args[2]))
elseif fsym.mod === Core && fsym.name === :_apply_iterate
f = getfield(mnokw.module, getsym(callexpr.args[3]))
else
f = getfield(fsym.mod, fsym.name)
end
else
f = missing
end
else
f = missing
end
else
f = missing
end
__bodyfunction__[mnokw] = f
end
return f
end

function _precompile_()
ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
Base.precompile(Tuple{typeof(Base.Broadcast.materialize),Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Nothing,typeof(RecipesPipeline._scaled_adapted_grid),Tuple{Array{Function,1},Base.RefValue{Symbol},Base.RefValue{Symbol},Float64,Float64}}})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol,Any},Array{Function,1},Number,Number})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol,Any},RecipesPipeline.GroupBy,Any})
Base.precompile(Tuple{typeof(RecipesBase.apply_recipe),AbstractDict{Symbol,Any},Type{RecipesPipeline.SliceIt},Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesPipeline._apply_type_recipe),Any,AbstractArray,Any})
Base.precompile(Tuple{typeof(RecipesPipeline._apply_type_recipe),Any,Surface,Any})
Base.precompile(Tuple{typeof(RecipesPipeline._extract_group_attributes),Array{String,1},Array{Float64,1}})
Base.precompile(Tuple{typeof(RecipesPipeline._map_funcs),Function,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}})
Base.precompile(Tuple{typeof(RecipesPipeline._process_plotrecipes!),Any,Any})
Base.precompile(Tuple{typeof(RecipesPipeline._process_ribbon),Tuple{LinRange{Float64},LinRange{Float64}},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._process_seriesrecipe),Any,Any})
Base.precompile(Tuple{typeof(RecipesPipeline._process_seriesrecipes!),Any,Any})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Array{AbstractArray{Float64,1},1},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Array{Array{Float64,1},1},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Array{Array{T,1} where T,1},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Array{Float64,2},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Array{Function,1},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Array{Int64,1},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Array{Real,1},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Array{String,1},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Array{Union{Missing, Int64},1},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Int64,Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),StepRange{Int64,Int64},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Surface{Array{Int64,2}},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline._series_data_vector),Surface{Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}},Dict{Symbol,Any}})
Base.precompile(Tuple{typeof(RecipesPipeline.recipe_pipeline!),Any,Any,Any})
Base.precompile(Tuple{typeof(RecipesPipeline.typerecipe_signature_string),typeof(atan)})
Base.precompile(Tuple{typeof(RecipesPipeline.unzip),Array{Tuple{Array{Float64,1},Array{Float64,1}},1}})
Base.precompile(Tuple{typeof(RecipesPipeline.unzip),Array{Tuple{Float64,Float64,Float64},1}})
Base.precompile(Tuple{typeof(RecipesPipeline.unzip),Array{Tuple{Int64,Real},1}})
Base.precompile(Tuple{typeof(copy),Base.Broadcast.Broadcasted{Base.Broadcast.Style{Tuple},Nothing,typeof(string),Tuple{Base.Broadcast.Broadcasted{Base.Broadcast.Style{Tuple},Nothing,typeof(typeof),Tuple{Tuple{Base.OneTo{Int64},Base.OneTo{Int64},Surface{Array{Int64,2}}}}}}}})
Base.precompile(Tuple{typeof(copy),Base.Broadcast.Broadcasted{Base.Broadcast.Style{Tuple},Nothing,typeof(string),Tuple{Base.Broadcast.Broadcasted{Base.Broadcast.Style{Tuple},Nothing,typeof(typeof),Tuple{Tuple{RecipesPipeline.GroupBy,Array{Float64,1}}}}}}})
Base.precompile(Tuple{typeof(copy),Base.Broadcast.Broadcasted{Base.Broadcast.Style{Tuple},Nothing,typeof(string),Tuple{Base.Broadcast.Broadcasted{Base.Broadcast.Style{Tuple},Nothing,typeof(typeof),Tuple{Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Surface{Array{Float64,2}}}}}}}})
Base.precompile(Tuple{typeof(setindex!),RecipesPipeline.DefaultsDict,StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Symbol})
let fbody = try __lookup_kwbody__(which(RecipesPipeline._extract_group_attributes, (Array{String,1},Array{Float64,1},))) catch missing end
if !ismissing(fbody)
precompile(fbody, (Function,typeof(RecipesPipeline._extract_group_attributes),Array{String,1},Array{Float64,1},))
end
end
end
10 changes: 10 additions & 0 deletions RecipesPipeline/deps/SnoopCompile/snoop_bench.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using CompileBot

snoop_bench(
BotConfig(
"RecipesPipeline",
yml_path= "SnoopCompile.yml",
else_os = "linux",
else_version = "1.5",
)
)
10 changes: 10 additions & 0 deletions RecipesPipeline/deps/SnoopCompile/snoop_bot.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using CompileBot

snoop_bot(
BotConfig(
"RecipesPipeline",
yml_path= "SnoopCompile.yml",
else_os = "linux",
else_version = "1.5",
)
)
5 changes: 4 additions & 1 deletion RecipesPipeline/src/RecipesPipeline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export warn_on_recipe_aliases,
slice_series_attributes!,
process_sliced_series_attributes!

include("api.jl")
include("utils.jl")
include("api.jl")
include("series.jl")
include("group.jl")
include("user_recipe.jl")
Expand All @@ -59,6 +59,7 @@ contains only the keyword arguments passed in by the user. Then, add all series
object `plt` and return it.
"""
function recipe_pipeline!(plt, plotattributes, args)
@nospecialize
plotattributes[:plot_object] = plt

# --------------------------------
Expand Down Expand Up @@ -102,4 +103,6 @@ function recipe_pipeline!(plt, plotattributes, args)
return plt
end

include("precompile_includer.jl")

end
10 changes: 9 additions & 1 deletion RecipesPipeline/src/api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@
Warn if an alias is dedected in `plotattributes` after a recipe of type `recipe_type` is
applied to 'args'. `recipe_type` is either `:user`, `:type`, `:plot` or `:series`.
"""
function warn_on_recipe_aliases!(plt, plotattributes, recipe_type, args...) end
function warn_on_recipe_aliases!(plt, plotattributes::AKW, recipe_type, signature_string) end
function warn_on_recipe_aliases!(plt, v::AbstractVector, recipe_type, signature_string)
for x in v
warn_on_recipe_aliases!(plt, x, recipe_type, signature_string)
end
end
function warn_on_recipe_aliases!(plt, rd::RecipeData, recipe_type, signature_string)
warn_on_recipe_aliases!(plt, rd.plotattributes, recipe_type, signature_string)
end


# ## Grouping
Expand Down
6 changes: 5 additions & 1 deletion RecipesPipeline/src/plot_recipe.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# # Plot Recipes

@nospecialize

"""
_process_plotrecipes!(plt, kw_list)
Expand Down Expand Up @@ -29,7 +31,7 @@ function _process_plotrecipe(plt, kw, kw_list, still_to_process)
st = kw[:seriestype]
st = kw[:seriestype] = type_alias(plt, st)
datalist = RecipesBase.apply_recipe(kw, Val{st}, plt)
warn_on_recipe_aliases!(plt, datalist, :plot, st)
warn_on_recipe_aliases!(plt, datalist, :plot, plotrecipe_signature_string(st))
for data in datalist
preprocess_attributes!(plt, data.plotattributes)
if data.plotattributes[:seriestype] == st
Expand All @@ -46,3 +48,5 @@ function _process_plotrecipe(plt, kw, kw_list, still_to_process)
end
return
end

@specialize
34 changes: 34 additions & 0 deletions RecipesPipeline/src/precompile_includer.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
should_precompile = true


# Don't edit the following! Instead change the script for `snoop_bot`.
ismultios = true
ismultiversion = true
# precompile_enclosure
@static if !should_precompile
# nothing
elseif !ismultios && !ismultiversion
include("../deps/SnoopCompile/precompile/precompile_RecipesPipeline.jl")
_precompile_()
else
@static if Sys.islinux()
@static if v"1.5.0-DEV" <= VERSION <= v"1.5.9"
include("../deps/SnoopCompile/precompile/linux/1.5/precompile_RecipesPipeline.jl")
_precompile_()
else
include("../deps/SnoopCompile/precompile/linux/1.5/precompile_RecipesPipeline.jl")
_precompile_()
end

else
@static if v"1.5.0-DEV" <= VERSION <= v"1.5.9"
include("../deps/SnoopCompile/precompile/linux/1.5/precompile_RecipesPipeline.jl")
_precompile_()
else
include("../deps/SnoopCompile/precompile/linux/1.5/precompile_RecipesPipeline.jl")
_precompile_()
end

end

end # precompile_enclosure
1 change: 1 addition & 0 deletions RecipesPipeline/src/series.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ struct SliceIt end
# It splits processed data into individual series data, stores in copied `plotattributes`
# for each series and returns no arguments.
@recipe function f(::Type{SliceIt}, x, y, z)
@nospecialize

# handle data with formatting attached
if typeof(x) <: Formatted
Expand Down
6 changes: 5 additions & 1 deletion RecipesPipeline/src/series_recipe.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# # Series Recipes

@nospecialize

"""
_process_seriesrecipes!(plt, kw_list)
Expand Down Expand Up @@ -46,7 +48,7 @@ function _process_seriesrecipe(plt, plotattributes)
# get a sub list of series for this seriestype
x, y, z = plotattributes[:x], plotattributes[:y], plotattributes[:z]
datalist = RecipesBase.apply_recipe(plotattributes, Val{st}, x, y, z)
warn_on_recipe_aliases!(plt, datalist, :series, st)
warn_on_recipe_aliases!(plt, datalist, :series, seriesrecipe_signature_string(st))

# assuming there was no error, recursively apply the series recipes
for data in datalist
Expand All @@ -64,3 +66,5 @@ function _process_seriesrecipe(plt, plotattributes)
end
nothing
end

@specialize
10 changes: 7 additions & 3 deletions RecipesPipeline/src/type_recipe.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# # Type Recipes

@nospecialize

# this is the default "type recipe"... just pass the object through
@recipe f(::Type{T}, v::T) where {T} = v

Expand All @@ -16,7 +18,7 @@ function _apply_type_recipe(plotattributes, v, letter)
plt = plotattributes[:plot_object]
preprocess_axis_args!(plt, plotattributes, letter)
rdvec = RecipesBase.apply_recipe(plotattributes, typeof(v), v)
warn_on_recipe_aliases!(plotattributes[:plot_object], plotattributes, :type, typeof(v))
warn_on_recipe_aliases!(plotattributes[:plot_object], plotattributes, :type, typerecipe_signature_string(v))
postprocess_axis_args!(plt, plotattributes, letter)
return rdvec[1].args[1]
end
Expand All @@ -29,13 +31,13 @@ function _apply_type_recipe(plotattributes, v::AbstractArray, letter)
preprocess_axis_args!(plt, plotattributes, letter)
# First we try to apply an array type recipe.
w = RecipesBase.apply_recipe(plotattributes, typeof(v), v)[1].args[1]
warn_on_recipe_aliases!(plt, plotattributes, :type, typeof(v))
warn_on_recipe_aliases!(plt, plotattributes, :type, typerecipe_signature_string(v))
# If the type did not change try it element-wise
if typeof(v) == typeof(w)
isempty(skipmissing(v)) && return Float64[]
x = first(skipmissing(v))
args = RecipesBase.apply_recipe(plotattributes, typeof(x), x)[1].args
warn_on_recipe_aliases!(plt, plotattributes, :type, typeof(x))
warn_on_recipe_aliases!(plt, plotattributes, :type, typerecipe_signature_string(x))
postprocess_axis_args!(plt, plotattributes, letter)
if length(args) == 2 && all(arg -> arg isa Function, args)
numfunc, formatter = args
Expand Down Expand Up @@ -70,3 +72,5 @@ _apply_type_recipe(
letter,
) = v
_apply_type_recipe(plotattributes, v::Nothing, letter) = v

@specialize
Loading

0 comments on commit e33afb0

Please sign in to comment.