Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor for allocations.jl #21

Merged
merged 8 commits into from
Dec 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
name: CI
on:
- push
- pull_request
jobs:
test:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
Expand All @@ -10,10 +9,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.6'
- '1.7'
- '1.8'
- "^1.9.0-0"
- "1.10"
- 'nightly'
os:
- ubuntu-latest
Expand Down
5 changes: 2 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
name = "PerfChecker"
uuid = "6309bf6b-a531-4b08-891e-8ee981e5c424"
authors = ["Azzaare <[email protected]>"]
version = "0.1.4"
version = "0.2.0"

[deps]
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
CoverageTools = "c36e975a-824b-4404-a568-ef97ca766997"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
GLM = "38e38edf-8417-5370-95a0-9cbb8c7f171a"
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
Expand All @@ -33,7 +32,7 @@ Plots = "1"
StatsPlots = "0.15"
Term = "2"
TypedTables = "1"
julia = "1.6"
julia = "1.10"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
1 change: 1 addition & 0 deletions perf/GLM/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
GLM = "38e38edf-8417-5370-95a0-9cbb8c7f171a"
PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925"
PerfChecker = "6309bf6b-a531-4b08-891e-8ee981e5c424"
PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
StatsModels = "3eaba693-59b7-5ba5-a881-562e759f1c8d"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
53 changes: 22 additions & 31 deletions perf/GLM/allocs.jl
Original file line number Diff line number Diff line change
@@ -1,34 +1,25 @@
using PerfChecker
using Test
using PerfChecker, PrettyTables

using GLM
using Random
using StatsModels

@testset "GLM.jl" begin
title = "Basic GLM computation"
dependencies = [GLM]
targets = [GLM]
x = @check :alloc Dict(:targets => ["GLM"], :path => @__DIR__) begin
using GLM, Random, StatsModels
end begin
n = 2_500_000
rng = Random.MersenneTwister(1234321)
tbl = (
x1=randn(rng, n),
x2=Random.randexp(rng, n),
ss=rand(rng, string.(50:99), n),
y=zeros(n),
)
f = @formula(y ~ 1 + x1 + x2 + ss)
f = apply_schema(f, schema(f, tbl))
resp, pred = modelcols(f, tbl)
B = randn(rng, size(pred, 2))
B[1] = 0.5
logistic(x::Real) = inv(1 + exp(-x))
resp .= rand(rng, n) .< logistic.(pred * B)
glm(pred, resp, Bernoulli())
end

function alloc()
n = 2_500_000
rng = Random.MersenneTwister(1234321)
tbl = (
x1 = randn(rng, n),
x2 = Random.randexp(rng, n),
ss = rand(rng, string.(50:99), n),
y = zeros(n),
)
f = @formula(y ~ 1 + x1 + x2 + ss)
f = apply_schema(f, schema(f, tbl))
resp, pred = modelcols(f, tbl)
B = randn(rng, size(pred, 2))
B[1] = 0.5
logistic(x::Real) = inv(1 + exp(-x))
resp .= rand(rng, n) .< logistic.(pred * B)
glm(pred, resp, Bernoulli())
return nothing
end

alloc_check(title, dependencies, targets, alloc, alloc; path=@__DIR__)
end
pretty_table(x |> to_table)
12 changes: 7 additions & 5 deletions src/PerfChecker.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ module PerfChecker

# SECTION - Imports
using BenchmarkTools
using CoverageTools
using CSV
using DataFrames
using Distributed
using LibGit2
using OrderedCollections
using PGFPlotsX
Expand All @@ -15,19 +13,23 @@ using Profile
using Random
using StatsPlots
using Term
using TypedTables
import TypedTables: Table
import Distributed: remotecall_fetch, addprocs, rmprocs
import CoverageTools: analyze_malloc_files, find_malloc_files, MallocInfo

# SECTION - Exports
export alloc_check
export alloc_plot
export bench_plot
export store_benchmark
export @check
export to_table

# SECTION - Includes

include("init.jl")

include("allocations.jl")
include("check.jl")
include("alloc.jl")
include("benchmarks.jl")
include("utils.jl")

Expand Down
49 changes: 49 additions & 0 deletions src/alloc.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
prep(d::Dict, block::Expr, ::Val{:alloc}) = quote
import Pkg
Pkg.instantiate()
import Profile
$block
nothing
end

function default_options(::Val{:alloc})
return Dict(:threads => 1, :targets => [], :track => "user", :repeat => true)
end

function check(d::Dict, block::Expr, ::Val{:alloc})

j = haskey(d, :repeat) && d[:repeat] ? block : nothing

quote
$j
Profile.clear_malloc_data()
$block
targets = eval(Meta.parse("[" * join($(d[:targets]), ", ") * "]"))
rmstuff = Base.loaded_modules_array()
if isempty(targets)
targets = Base.loaded_modules_array()
end
return dirname.(filter(!isnothing, pathof.(targets))), dirname.(filter(!isnothing, pathof.(rmstuff)))
end
end

function post(d::Dict, ::Val{:alloc})
result = d[:check_result]
files = find_malloc_files(result[1])
delete_files = find_malloc_files(result[2])
myallocs = analyze_malloc_files(files)
if !isempty(myallocs)
rm.(delete_files)
else
@error "No allocation files found in $(d[:targets])"
end
myallocs
end

function to_table(myallocs::Vector{MallocInfo})
b = map(a -> a.bytes, Iterators.reverse(myallocs))
r = round.(b / sum(b) * 100; digits=2)
f = map(first ∘ splitext ∘ first ∘ splitext, map(a -> a.filename, Iterators.reverse(myallocs)))
l = map(a -> a.linenumber, Iterators.reverse(myallocs))
Table(bytes=b, percentage=r, filenames=f, linenumbers=l)
end
151 changes: 0 additions & 151 deletions src/allocations.jl

This file was deleted.

42 changes: 42 additions & 0 deletions src/check.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
prep(d, b, v) = quote nothing end
check(d, b, v) = quote nothing end
post(d, v) = nothing
default_options(v) = Dict()

prep(d::Dict, b::Expr, v::Symbol) = prep(d, b, Val(v))
check(d::Dict, b::Expr, v::Symbol) = check(d, b, Val(v))
post(d::Dict, v::Symbol) = post(d, Val(v))

function default_options(d::Dict, v::Symbol)
di = default_options(Val(v))
return merge(di, d)
end

macro check(x, d, block1, block2)
block1, block2 = Expr(:quote, block1), Expr(:quote, block2)
quote
di = default_options($d, $x)
g = prep(di, $block1, $x)
h = check(di, $block2, $x)
p = remotecall_fetch(Core.eval, 1, Main,
Expr(:toplevel, quote
import Distributed
d = $di
Distributed.addprocs(1; exeflags=["--track-allocation=$(d[:track])", "--project=$(d[:path])", "-t $(d[:threads])"])
end).args...) |> first

di[:prep_result] = remotecall_fetch(Core.eval, p, Main,
Expr(:toplevel, g.args...))

di[:check_result] = remotecall_fetch(Core.eval, p, Main,
Expr(:toplevel, h.args...))

remotecall_fetch(Core.eval, 1, Main,
Expr(:toplevel, quote
import Distributed
Distributed.rmprocs($p)
end).args...)

$post(di, $x)
end
end
Loading