Skip to content

Commit b40501a

Browse files
Merge pull request #6 from AtelierArith/terasaki/support-apple-M-series-monitoring
Support apple M series monitoring
2 parents c507351 + ec17c3e commit b40501a

File tree

4 files changed

+129
-27
lines changed

4 files changed

+129
-27
lines changed

Project.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,21 @@ MLDataDevices = "7e8f7934-dd98-4c1a-8fe8-92b47a384d40"
99
Term = "22787eb5-b846-44ae-b979-8e399b8463ab"
1010
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"
1111

12-
[extensions]
13-
TerminalSystemMonitorCUDAExt = "CUDA"
14-
1512
[weakdeps]
1613
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
14+
MacOSIOReport = "27799fc1-e272-4181-9793-a9e1fcba685b"
15+
16+
[extensions]
17+
TerminalSystemMonitorCUDAExt = "CUDA"
18+
TerminalSystemMonitorMacOSIOReportExt = "MacOSIOReport"
1719

1820
[compat]
1921
Aqua = "0.8.9"
2022
CUDA = "5.5.2"
2123
Dates = "1"
2224
JET = "0.9.12"
2325
MLDataDevices = "1.5.3"
26+
MacOSIOReport = "0.1.0"
2427
ReTestItems = "1.29.0"
2528
Term = "2.0.6"
2629
Test = "1"
@@ -29,10 +32,9 @@ julia = "1.10"
2932

3033
[extras]
3134
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
32-
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
3335
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
3436
ReTestItems = "817f1d60-ba6b-4fd5-9520-3cf149f6a823"
3537
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3638

3739
[targets]
38-
test = ["Aqua", "JET", "ReTestItems", "Test", "CUDA"]
40+
test = ["Aqua", "JET", "ReTestItems", "Test"]

ext/TerminalSystemMonitorCUDAExt/TerminalSystemMonitorCUDAExt.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function _plot_gpu_utilization_rates(gpu_id, dev::CUDA.CuDevice)
1111
nvml_dev = CUDA.NVML.Device(uuid(dev); mig)
1212
x = string(gpu_id)
1313
y = 100 * CUDA.NVML.utilization_rates(nvml_dev).compute
14-
return barplot([x], [y], maximum = 100, width = max(5, 15))
14+
return barplot([x], [y], maximum = 100, width = 15)
1515
end
1616

1717
function TerminalSystemMonitor.plot_gpu_utilization_rates(::Type{CUDADevice})
@@ -56,7 +56,7 @@ function _plot_gpu_memory_utilization(dev::CUDA.CuDevice)
5656
# Adds a space for better styling
5757
name = " $(memorytotal) $(memorytotal_unit)",
5858
maximum = memorytotal,
59-
width = max(5, 15),
59+
width = 15,
6060
)
6161
end
6262

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
module TerminalSystemMonitorMacOSIOReportExt
2+
3+
using MLDataDevices: MetalDevice
4+
using UnicodePlots: barplot
5+
import TerminalSystemMonitor
6+
using MacOSIOReport: Sampler, get_metrics, MTLDevice
7+
using TerminalSystemMonitor: extract_number_and_unit
8+
9+
function _plot_cpu_utilization_rates(id, usage)
10+
x = string(id)
11+
y = usage
12+
return barplot([x], [y], maximum = 100, width = 15)
13+
end
14+
15+
function TerminalSystemMonitor.plot_cpu_utilization_rates(::Type{MetalDevice})
16+
sampler = Sampler()
17+
msec = UInt(500)
18+
m = get_metrics(sampler, msec)
19+
cpu_ids = ["E-CPU: ", "P-CPU: "]
20+
usages = [
21+
round(100 * m.ecpu_usage[2], digits = 1),
22+
round(100 * m.pcpu_usage[2], digits = 1),
23+
]
24+
return Any[barplot(cpu_ids, usages, maximum = 100, width = 15)]
25+
end
26+
27+
function TerminalSystemMonitor.plot_gpu_utilization_rates(::Type{MetalDevice})
28+
sampler = Sampler()
29+
msec = UInt(500)
30+
m = get_metrics(sampler, msec)
31+
gpu_usages = [
32+
("GPU: ", round(100 * m.gpu_usage[2], digits = 1)),
33+
]
34+
plts = []
35+
chip_name = String(MTLDevice(1).name)
36+
push!(
37+
plts, barplot(["GPU: "], [round(100 * m.gpu_usage[2], digits = 1)], xlabel=chip_name, maximum=100, width=15)
38+
)
39+
return plts
40+
end
41+
42+
end # module TerminalSystemMonitorMacOSIOReportExt

src/TerminalSystemMonitor.jl

Lines changed: 78 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ module TerminalSystemMonitor
33
using Dates: Dates, Day, DateTime, Second
44
using UnicodePlots
55
import Term # this is required by UnicodePlots.panel
6-
using MLDataDevices: MLDataDevices, CUDADevice
6+
using MLDataDevices: MLDataDevices, CUDADevice, CPUDevice, MetalDevice
77

88
export monitor # entrypoint from REPL
99

1010
# These function will be defined in Package extensions
11+
function plot_cpu_utilization_rates end
1112
function plot_gpu_utilization_rates end
1213
function plot_gpu_memory_utilization end
1314

@@ -77,7 +78,7 @@ function extract_number_and_unit(str::AbstractString)
7778
end
7879
end
7980

80-
function plot_cpu_utilization_rates()
81+
function plot_cpu_utilization_rates(::Type{CPUDevice})
8182
ys = get_cpu_percent()
8283
npad = 1 + floor(Int, log10(length(ys)))
8384
xs = ["id: $(lpad(i-1, npad))" for (i, _) in enumerate(ys)]
@@ -94,7 +95,7 @@ function plot_cpu_utilization_rates()
9495
return plts
9596
end
9697

97-
function plot_cpu_memory_utilization()
98+
function plot_cpu_memory_utilization(::Type{CPUDevice})
9899
memorytotal, memorytotal_unit =
99100
Sys.total_memory() |> Base.format_bytes |> extract_number_and_unit
100101
memoryfree, _ = Sys.free_memory() |> Base.format_bytes |> extract_number_and_unit
@@ -140,42 +141,99 @@ function main(dummyargs...)
140141

141142
while true
142143
try
143-
plts = []
144-
append!(plts, plot_cpu_utilization_rates())
145144
_, cols = displaysize(stdout)
146-
n = max(1, cols ÷ 25)
147-
chunks = collect(Iterators.partition(plts, n))
148-
f = foldl(/, map(c -> prod(UnicodePlots.panel.(c)), chunks))
149-
150-
f /= prod(UnicodePlots.panel.(plot_cpu_memory_utilization()))
145+
t1 = @async begin
146+
try
147+
plts = []
148+
append!(plts, plot_cpu_utilization_rates(CPUDevice))
149+
n = max(1, cols ÷ 25)
150+
chunks = collect(Iterators.partition(plts, n))
151+
f = foldl(/, map(c -> prod(UnicodePlots.panel.(c)), chunks))
152+
153+
f /= prod(UnicodePlots.panel.(plot_cpu_memory_utilization(CPUDevice)))
154+
return f
155+
catch e
156+
if e isa InterruptException
157+
return nothing
158+
else
159+
rethrow(e)
160+
end
161+
end
162+
end
151163

152164
if isdefined(Main, :CUDA) &&
153165
getproperty(getproperty(Main, :CUDA), :functional)()
166+
wait(t1)
167+
f = fetch(t1)
168+
if isnothing(f)
169+
break
170+
end
154171
cudaplts = []
155172
n = max(1, cols ÷ 50)
156-
plts1 = plot_gpu_utilization_rates(MLDataDevices.CUDADevice)::Vector{Any}
157-
plts2 = plot_gpu_memory_utilization(MLDataDevices.CUDADevice)::Vector{Any}
173+
plts1 = plot_gpu_utilization_rates(CUDADevice)::Vector{Any}
174+
plts2 = plot_gpu_memory_utilization(CUDADevice)::Vector{Any}
158175
for i in eachindex(plts1, plts2)
159176
push!(cudaplts, plts1[i])
160177
push!(cudaplts, plts2[i])
161178
end
162179
gpuchunks = collect(Iterators.partition(cudaplts, n))
163180
f /= foldl(/, map(c -> prod(UnicodePlots.panel.(c)), gpuchunks))
181+
elseif isdefined(Main, :MacOSIOReport) && Sys.isapple() && Sys.ARCH == :aarch64
182+
metalplts = []
183+
n = max(1, cols ÷ 50)
184+
t2 = @async begin
185+
try
186+
return plot_cpu_utilization_rates(MetalDevice)
187+
catch e
188+
if e isa InterruptException
189+
return nothing
190+
else
191+
rethrow(e)
192+
end
193+
end
194+
end
195+
t3 = @async begin
196+
try
197+
return plot_gpu_utilization_rates(MetalDevice)
198+
catch e
199+
if e isa InterruptException
200+
return nothing
201+
else
202+
rethrow(e)
203+
end
204+
end
205+
end
206+
wait(t1)
207+
wait(t2)
208+
wait(t3)
209+
plts1 = fetch(t2)
210+
plts2 = fetch(t3)
211+
if isnothing(plts1) || isnothing(plts2)
212+
break
213+
end
214+
for i in eachindex(plts1)
215+
push!(metalplts, plts1[i])
216+
end
217+
for i in eachindex(plts2)
218+
push!(metalplts, plts2[i])
219+
end
220+
metalchunks = collect(Iterators.partition(metalplts, n))
221+
f /= foldl(/, map(c -> prod(UnicodePlots.panel.(c)), metalchunks))
222+
else
223+
wait(t1)
224+
f = fetch(t1)
225+
if isnothing(f)
226+
break
227+
end
164228
end
165229
clearlinesall()
166230
display(f)
167231
catch e
168232
unhidecursor() # unhide cursor
169-
if e isa InterruptException
170-
@info "Intrrupted"
171-
break
172-
else
173-
@warn "Got Exception"
174-
rethrow(e) # so we don't swallow true exceptions
175-
end
233+
@warn "Got Exception"
234+
rethrow(e) # so we don't swallow true exceptions
176235
end
177236
end
178-
@info "Unhide cursor"
179237
unhidecursor() # unhide cursor
180238
end
181239

0 commit comments

Comments
 (0)