From 94a0f98c8b75ad8eeab4c680fa6b700d319d5beb Mon Sep 17 00:00:00 2001 From: Zentrik Date: Sat, 30 Dec 2023 12:58:40 +0000 Subject: [PATCH 1/9] Add some copy methods and convert for deserialization. This is useful for https://github.com/JuliaCI/BenchmarkTools.jl/pull/347 --- src/LinuxPerf.jl | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/LinuxPerf.jl b/src/LinuxPerf.jl index e330e92..bc0dfcc 100644 --- a/src/LinuxPerf.jl +++ b/src/LinuxPerf.jl @@ -118,6 +118,12 @@ struct EventType event::UInt64 end +Base.copy(event::EventType) = EventType(event.category, event.event) + +function Base.convert(::Type{EventType}, d::Dict{String}) + return EventType(d["category"], d["event"]) +end + function all_events() evts = EventType[] for (cat_name, cat_id, events) in EVENT_TYPES @@ -356,6 +362,18 @@ struct Counter running::UInt64 end +function Base.copy(counter::Counter) + return Counter( + copy(counter.event), counter.value, counter.enabled, counter.running + ) +end + +function Base.convert(::Type{Counter}, d::Dict{String}) + return Counter( + convert(EventType, d["event"]), d["value"], d["enabled"], d["running"] + ) +end + struct Counters counters::Vector{Counter} end @@ -734,6 +752,14 @@ struct ThreadStats groups::Vector{Vector{Counter}} end +function Base.copy(thread_stats::ThreadStats) + return ThreadStats(thread_stats.pid, copy(thread_stats.groups)) +end + +function Base.convert(::Type{ThreadStats}, d::Dict{String}) + return ThreadStats(d["pid"], d["groups"]) +end + function ThreadStats(b::PerfBench) groups = Vector{Counter}[] for g in b.groups @@ -775,6 +801,10 @@ struct Stats threads::Vector{ThreadStats} end +Base.copy(stats::Stats) = Stats(copy(stats.threads)) + +Base.convert(::Type{Stats}, d::Dict{String}) = Stats(d["threads"]) + Stats(b::PerfBenchThreaded) = Stats(map(ThreadStats, b.data)) Base.show(io::IO, stats::Stats) = printsummary(io, stats) From 63b866a87fa2c85b20291d575b8b0131f5b20c4c Mon Sep 17 00:00:00 2001 From: Zentrik Date: Sat, 30 Dec 2023 14:00:50 +0000 Subject: [PATCH 2/9] Add custom JSON lowering for parsed pstat options --- Project.toml | 6 ++++++ ext/JSONExt.jl | 10 ++++++++++ 2 files changed, 16 insertions(+) create mode 100644 ext/JSONExt.jl diff --git a/Project.toml b/Project.toml index c10e12c..30d9473 100644 --- a/Project.toml +++ b/Project.toml @@ -7,6 +7,12 @@ Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0" PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +[weakdeps] +JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" + +[extensions] +JSONExt = "JSON" + [compat] Formatting = "0.4" PrettyTables = "2" diff --git a/ext/JSONExt.jl b/ext/JSONExt.jl new file mode 100644 index 0000000..33d83cd --- /dev/null +++ b/ext/JSONExt.jl @@ -0,0 +1,10 @@ +# compatiability with serializing parsed pstat options with JSON.jl + +module JSONExt + +using LinuxPerf: parse_groups +using JSON + +JSON.lower(::typeof(parse_groups)) = "LinuxPerf.parse_groups" + +end \ No newline at end of file From f0cee90b3bb6c6b6630ec5ff024cd0214f53b606 Mon Sep 17 00:00:00 2001 From: Zentrik Date: Sat, 30 Dec 2023 14:03:26 +0000 Subject: [PATCH 3/9] Add tests --- test/Project.toml | 1 + test/runtests.jl | 60 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/test/Project.toml b/test/Project.toml index 0c36332..8920e1f 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,2 +1,3 @@ [deps] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index ec96e18..3047373 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,7 +1,8 @@ using LinuxPerf using Test +using JSON -using LinuxPerf: make_bench, enable!, disable!, reset!, reasonable_defaults, counters, EventType, EventTypeExt, parse_groups +using LinuxPerf: make_bench, enable!, disable!, reset!, reasonable_defaults, counters, EventType, EventTypeExt, parse_groups, Counter, ThreadStats, Stats, parse_pstats_options @testset "LinuxPerf" begin @@ -97,5 +98,62 @@ end @pstats "cpu-cycles,(instructions,branch-instructions,branch-misses),(task-clock,context-switches,cpu-migrations,page-faults),(L1-dcache-load-misses,L1-dcache-loads,L1-icache-load-misses),(dTLB-load-misses,dTLB-loads)" foo!(dest, a, b, c) end +@testset "copy structs" begin + event = EventType(:hw, :cycles) + @test_nowarn copy(event) + @test copy(event) === event + + counter = Counter(event, 1, 2, 3) + @test_nowarn copy(counter) + @test copy(counter) === counter + + thread_stats = ThreadStats(0, [[counter, counter]]) + @test_nowarn copy(thread_stats) + copied_thread_stats = copy(thread_stats) + @test copied_thread_stats.pid == thread_stats.pid + @test copied_thread_stats.groups == thread_stats.groups + @test copied_thread_stats.groups !== thread_stats.groups + + stats = Stats([thread_stats]) + @test_nowarn copy(stats) + copied_stats = copy(stats) + @test copied_stats.threads == stats.threads + @test copied_stats.threads !== stats.threads +end + +@testset "convert structs from dicts" begin + event_dict = Dict("category"=>0, "event"=>1) + event = EventType(0, 1) + + counter_dict = Dict("event"=>event_dict, "value"=>1, "enabled"=>2, "running"=>3) + counter = Counter(event, 1, 2, 3) + + thread_stats_dict = Dict("pid"=>0, "groups"=>[[counter_dict, counter_dict]]) + thread_stats = ThreadStats(0, [[counter, counter]]) + + stats_dict = Dict("threads"=>[thread_stats_dict]) + stats = Stats([thread_stats]) + + @test convert(EventType, event_dict) == event + @test convert(Counter, counter_dict) == counter + + converted_thread_stats = convert(ThreadStats, thread_stats_dict) + @test converted_thread_stats.pid == thread_stats.pid + @test converted_thread_stats.groups == thread_stats.groups + + converted_stats = convert(Stats, stats_dict) + @test all(x -> x[1].pid == x[2].pid && x[1].groups == x[2].groups, zip(converted_stats.threads, stats.threads)) +end + +@testset "Serialize Tests" begin + @test_nowarn JSON.print(devnull, parse_pstats_options([])) + + event = EventType(0, 1) + counter = Counter(event, 1, 2, 3) + thread_stats = ThreadStats(0, [[counter, counter]]) + stats = Stats([thread_stats]) + + @test_nowarn JSON.print(devnull, stats) +end end \ No newline at end of file From 7c3ca2d2cdbecd0771a2eee342573d65c205463f Mon Sep 17 00:00:00 2001 From: Zentrik Date: Sat, 30 Dec 2023 14:32:53 +0000 Subject: [PATCH 4/9] Support JSON extension on Julia versions < 1.9 --- Project.toml | 16 ++++++++++------ ext/JSONExt.jl | 2 +- src/LinuxPerf.jl | 10 ++++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Project.toml b/Project.toml index 30d9473..1df70de 100644 --- a/Project.toml +++ b/Project.toml @@ -6,14 +6,18 @@ version = "0.3.6" Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0" PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[weakdeps] -JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" - -[extensions] -JSONExt = "JSON" +Requires = "ae029012-a4dd-5104-9daa-d747884805df" [compat] Formatting = "0.4" PrettyTables = "2" julia = "1" + +[extensions] +JSONExt = "JSON" + +[extras] +JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" + +[weakdeps] +JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" diff --git a/ext/JSONExt.jl b/ext/JSONExt.jl index 33d83cd..859b74a 100644 --- a/ext/JSONExt.jl +++ b/ext/JSONExt.jl @@ -3,7 +3,7 @@ module JSONExt using LinuxPerf: parse_groups -using JSON +isdefined(Base, :get_extension) ? (import JSON) : (import ..JSON) JSON.lower(::typeof(parse_groups)) = "LinuxPerf.parse_groups" diff --git a/src/LinuxPerf.jl b/src/LinuxPerf.jl index bc0dfcc..c545ff5 100644 --- a/src/LinuxPerf.jl +++ b/src/LinuxPerf.jl @@ -1,5 +1,15 @@ module LinuxPerf +if !isdefined(Base, :get_extension) + using Requires +end + +@static if !isdefined(Base, :get_extension) + function __init__() + @require JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" begin include("../ext/JSONExt.jl") end + end +end + using Printf using PrettyTables using Formatting From be88a9b9418630d6d4d661290476f6ee2529fe19 Mon Sep 17 00:00:00 2001 From: Zentrik Date: Wed, 3 Jan 2024 17:32:43 +0000 Subject: [PATCH 5/9] Remove serialization of pstat options --- Project.toml | 12 +----------- ext/JSONExt.jl | 10 ---------- src/LinuxPerf.jl | 10 ---------- test/Project.toml | 3 +-- test/runtests.jl | 5 +---- 5 files changed, 3 insertions(+), 37 deletions(-) delete mode 100644 ext/JSONExt.jl diff --git a/Project.toml b/Project.toml index 1df70de..f9d8c05 100644 --- a/Project.toml +++ b/Project.toml @@ -6,18 +6,8 @@ version = "0.3.6" Formatting = "59287772-0a20-5a39-b81b-1366585eb4c0" PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" -Requires = "ae029012-a4dd-5104-9daa-d747884805df" [compat] Formatting = "0.4" PrettyTables = "2" -julia = "1" - -[extensions] -JSONExt = "JSON" - -[extras] -JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" - -[weakdeps] -JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +julia = "1" \ No newline at end of file diff --git a/ext/JSONExt.jl b/ext/JSONExt.jl deleted file mode 100644 index 859b74a..0000000 --- a/ext/JSONExt.jl +++ /dev/null @@ -1,10 +0,0 @@ -# compatiability with serializing parsed pstat options with JSON.jl - -module JSONExt - -using LinuxPerf: parse_groups -isdefined(Base, :get_extension) ? (import JSON) : (import ..JSON) - -JSON.lower(::typeof(parse_groups)) = "LinuxPerf.parse_groups" - -end \ No newline at end of file diff --git a/src/LinuxPerf.jl b/src/LinuxPerf.jl index c545ff5..bc0dfcc 100644 --- a/src/LinuxPerf.jl +++ b/src/LinuxPerf.jl @@ -1,15 +1,5 @@ module LinuxPerf -if !isdefined(Base, :get_extension) - using Requires -end - -@static if !isdefined(Base, :get_extension) - function __init__() - @require JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" begin include("../ext/JSONExt.jl") end - end -end - using Printf using PrettyTables using Formatting diff --git a/test/Project.toml b/test/Project.toml index 8920e1f..700082b 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,3 +1,2 @@ [deps] -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" \ No newline at end of file +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 3047373..8e6c96a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,8 +1,7 @@ using LinuxPerf using Test -using JSON -using LinuxPerf: make_bench, enable!, disable!, reset!, reasonable_defaults, counters, EventType, EventTypeExt, parse_groups, Counter, ThreadStats, Stats, parse_pstats_options +using LinuxPerf: make_bench, enable!, disable!, reset!, reasonable_defaults, counters, EventType, EventTypeExt, parse_groups, Counter, ThreadStats, Stats @testset "LinuxPerf" begin @@ -146,8 +145,6 @@ end end @testset "Serialize Tests" begin - @test_nowarn JSON.print(devnull, parse_pstats_options([])) - event = EventType(0, 1) counter = Counter(event, 1, 2, 3) thread_stats = ThreadStats(0, [[counter, counter]]) From 72c41c433812860504609ef03195ff7849af394e Mon Sep 17 00:00:00 2001 From: Zentrik Date: Wed, 3 Jan 2024 17:39:20 +0000 Subject: [PATCH 6/9] Revert whitespace change and remove JSON tests --- Project.toml | 2 +- test/runtests.jl | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/Project.toml b/Project.toml index f9d8c05..c10e12c 100644 --- a/Project.toml +++ b/Project.toml @@ -10,4 +10,4 @@ Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" [compat] Formatting = "0.4" PrettyTables = "2" -julia = "1" \ No newline at end of file +julia = "1" diff --git a/test/runtests.jl b/test/runtests.jl index 8e6c96a..d542b13 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -144,13 +144,4 @@ end @test all(x -> x[1].pid == x[2].pid && x[1].groups == x[2].groups, zip(converted_stats.threads, stats.threads)) end -@testset "Serialize Tests" begin - event = EventType(0, 1) - counter = Counter(event, 1, 2, 3) - thread_stats = ThreadStats(0, [[counter, counter]]) - stats = Stats([thread_stats]) - - @test_nowarn JSON.print(devnull, stats) -end - end \ No newline at end of file From 8d40170b1063091ca88379e98b09947810b852a3 Mon Sep 17 00:00:00 2001 From: Zentrik Date: Wed, 3 Jan 2024 17:50:56 +0000 Subject: [PATCH 7/9] Revert whitespace change [no-ci] --- test/Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Project.toml b/test/Project.toml index 700082b..0c36332 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,2 +1,2 @@ [deps] -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" \ No newline at end of file +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" From 149f3b438803866bde0774fd8d9bc616e2f2837b Mon Sep 17 00:00:00 2001 From: Zentrik Date: Sun, 7 Jan 2024 23:00:37 +0000 Subject: [PATCH 8/9] Remove convert methods --- src/LinuxPerf.jl | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/LinuxPerf.jl b/src/LinuxPerf.jl index bc0dfcc..aef2e37 100644 --- a/src/LinuxPerf.jl +++ b/src/LinuxPerf.jl @@ -120,10 +120,6 @@ end Base.copy(event::EventType) = EventType(event.category, event.event) -function Base.convert(::Type{EventType}, d::Dict{String}) - return EventType(d["category"], d["event"]) -end - function all_events() evts = EventType[] for (cat_name, cat_id, events) in EVENT_TYPES @@ -368,12 +364,6 @@ function Base.copy(counter::Counter) ) end -function Base.convert(::Type{Counter}, d::Dict{String}) - return Counter( - convert(EventType, d["event"]), d["value"], d["enabled"], d["running"] - ) -end - struct Counters counters::Vector{Counter} end @@ -756,10 +746,6 @@ function Base.copy(thread_stats::ThreadStats) return ThreadStats(thread_stats.pid, copy(thread_stats.groups)) end -function Base.convert(::Type{ThreadStats}, d::Dict{String}) - return ThreadStats(d["pid"], d["groups"]) -end - function ThreadStats(b::PerfBench) groups = Vector{Counter}[] for g in b.groups @@ -803,8 +789,6 @@ end Base.copy(stats::Stats) = Stats(copy(stats.threads)) -Base.convert(::Type{Stats}, d::Dict{String}) = Stats(d["threads"]) - Stats(b::PerfBenchThreaded) = Stats(map(ThreadStats, b.data)) Base.show(io::IO, stats::Stats) = printsummary(io, stats) From b8f1d01850ffe7e01714f4d76c36ec1cc2825380 Mon Sep 17 00:00:00 2001 From: Zentrik Date: Sun, 7 Jan 2024 23:24:19 +0000 Subject: [PATCH 9/9] Remove tests for removed convert methods --- test/runtests.jl | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index d542b13..6c3fee8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -120,28 +120,4 @@ end @test copied_stats.threads !== stats.threads end -@testset "convert structs from dicts" begin - event_dict = Dict("category"=>0, "event"=>1) - event = EventType(0, 1) - - counter_dict = Dict("event"=>event_dict, "value"=>1, "enabled"=>2, "running"=>3) - counter = Counter(event, 1, 2, 3) - - thread_stats_dict = Dict("pid"=>0, "groups"=>[[counter_dict, counter_dict]]) - thread_stats = ThreadStats(0, [[counter, counter]]) - - stats_dict = Dict("threads"=>[thread_stats_dict]) - stats = Stats([thread_stats]) - - @test convert(EventType, event_dict) == event - @test convert(Counter, counter_dict) == counter - - converted_thread_stats = convert(ThreadStats, thread_stats_dict) - @test converted_thread_stats.pid == thread_stats.pid - @test converted_thread_stats.groups == thread_stats.groups - - converted_stats = convert(Stats, stats_dict) - @test all(x -> x[1].pid == x[2].pid && x[1].groups == x[2].groups, zip(converted_stats.threads, stats.threads)) -end - end \ No newline at end of file