macpm 0.15__tar.gz → 0.22__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: macpm
3
- Version: 0.15
3
+ Version: 0.22
4
4
  Summary: Performance monitoring CLI tool for Apple Silicon
5
5
  Home-page: https://github.com/visualcjy/macpm
6
6
  Author: Jinyu Chen
@@ -5,8 +5,8 @@ or: pip install macpm
5
5
 
6
6
  enhanced MAC Performance monitoring CLI tool for Apple Silicon
7
7
 
8
- ![](images/macpm.png)
9
-
8
+ ![](images/macpm-v.gif)
9
+ ![](images/macpm.gif)
10
10
  ```shell
11
11
  pip install macpm
12
12
  ```
@@ -19,6 +19,7 @@ forked form https://github.com/tlkh/asitop
19
19
  3. adjust the hard coded max power in CPU/GPU/ANE
20
20
  4. change the way to call powermetrics, no temp files in /tmp
21
21
  5. press ESC or q to quit
22
+ 6. press LEFT or RIGHT to switch color, press 1 : default view, 2 : show_core view
22
23
 
23
24
  A Python-based `nvtop`-inspired command line tool for Apple Silicon (aka M1) Macs.
24
25
 
@@ -9,7 +9,7 @@ import psutil
9
9
  import plistlib
10
10
  import curses
11
11
 
12
- version = 'macpm v0.15'
12
+ version = 'macpm v0.22'
13
13
  parser = argparse.ArgumentParser(
14
14
  description=f'{version}: Performance monitoring CLI tool for Apple Silicon')
15
15
  parser.add_argument('--interval', type=int, default=1,
@@ -253,12 +253,13 @@ def parse_cpu_metrics(powermetrics_parse):
253
253
  core = e_core if name[0] == 'E' else p_core
254
254
  core.append(cpu["cpu"])
255
255
  cpu_metric_dict[name + str(cpu["cpu"]) + "_freq_Mhz"] = int(cpu["freq_hz"] / (1e6))
256
- cpu_metric_dict[name + str(cpu["cpu"]) + "_active"] = int((1 - cpu["idle_ratio"]) * 100)
256
+ idle_ratio = cluster["down_ratio"] + (1 - cluster["down_ratio"]) * (cpu["idle_ratio"] + cpu["down_ratio"])
257
+ cpu_metric_dict[name + str(cpu["cpu"]) + "_active"] = int((1 - idle_ratio) * 100)
257
258
  if name[0] == 'E':
258
- e_total_idle_ratio += cluster["down_ratio"] + (1 - cluster["down_ratio"]) * (cpu["idle_ratio"] + cpu["down_ratio"])
259
+ e_total_idle_ratio += idle_ratio
259
260
  e_core_count += 1
260
261
  else:
261
- p_total_idle_ratio += cluster["down_ratio"] + (1 - cluster["down_ratio"]) * (cpu["idle_ratio"] + cpu["down_ratio"])
262
+ p_total_idle_ratio += idle_ratio
262
263
  p_core_count += 1
263
264
 
264
265
  cpu_metric_dict["E-Cluster_active"] = int((1 - e_total_idle_ratio/e_core_count)*100)
@@ -340,6 +341,7 @@ class DefaultView():
340
341
  self.disk_write_bps_peak = 0
341
342
  self.network_in_bps_peak = 0
342
343
  self.network_out_bps_peak = 0
344
+ self.default_cpu_perline = 8
343
345
  self.construct(soc_info_dict,args)
344
346
 
345
347
  def construct(self,soc_info_dict,args):
@@ -351,15 +353,34 @@ class DefaultView():
351
353
  self.e_core_count = soc_info_dict["e_core_count"]
352
354
  self.e_core_gauges = [VGauge(val=0, color=args.color, border_color=args.color) for _ in range(self.e_core_count)]
353
355
  self.p_core_count = soc_info_dict["p_core_count"]
354
- self.p_core_gauges = [VGauge(val=0, color=args.color, border_color=args.color) for _ in range(min(self.p_core_count, 8))]
355
- self.p_core_split = [HSplit(
356
- *self.p_core_gauges,
357
- )]
358
- if self.p_core_count > 8:
359
- self.p_core_gauges_ext = [VGauge(val=0, color=args.color, border_color=args.color) for _ in range(self.p_core_count - 8)]
356
+ self.max_cpu_perline = self.default_cpu_perline
357
+ for i in range(int(self.default_cpu_perline/2),self.default_cpu_perline):
358
+ if self.p_core_count % i == 0:
359
+ self.max_cpu_perline = i
360
+ break
361
+ import math
362
+ p_core_lines = math.ceil(self.p_core_count / self.max_cpu_perline)
363
+ self.p_core_gauges = []
364
+ self.p_core_split = []
365
+ for i in range(p_core_lines):
366
+ self.p_core_gauges.append([])
367
+ self.p_core_gauges[i].extend([VGauge(val=0, color=args.color, border_color=args.color) for _ in range(self.max_cpu_perline if i < p_core_lines - 1 else self.p_core_count - i * self.max_cpu_perline)])
360
368
  self.p_core_split.append(HSplit(
361
- *self.p_core_gauges_ext,
369
+ *self.p_core_gauges[i],
362
370
  ))
371
+ if args.show_cores:
372
+ self.processor_gauges = [self.cpu1_gauge,
373
+ HSplit(*self.e_core_gauges),
374
+ self.cpu2_gauge,]
375
+ #for i in range(len(self.p_core_split)):
376
+ self.processor_gauges.extend(self.p_core_split)
377
+ self.processor_gauges.extend(self.gpu_ane_gauges)
378
+ else:
379
+ self.processor_gauges = [
380
+ HSplit(self.cpu1_gauge, self.cpu2_gauge),
381
+ HSplit(*self.gpu_ane_gauges)
382
+ ]
383
+ """
363
384
  self.processor_gauges = [self.cpu1_gauge,
364
385
  HSplit(*self.e_core_gauges),
365
386
  self.cpu2_gauge,
@@ -369,6 +390,7 @@ class DefaultView():
369
390
  HSplit(self.cpu1_gauge, self.cpu2_gauge),
370
391
  HSplit(*self.gpu_ane_gauges)
371
392
  ]
393
+ """
372
394
  self.processor_split = VSplit(
373
395
  *self.processor_gauges,
374
396
  title="Processor Utilization",
@@ -515,12 +537,14 @@ class DefaultView():
515
537
  self.e_core_gauges[i].color = args.color
516
538
  self.e_core_gauges[i].border_color = args.color
517
539
  for i in range(len(self.p_core_gauges)):
518
- self.p_core_gauges[i].color = args.color
519
- self.p_core_gauges[i].border_color = args.color
540
+ for j in range(len(self.p_core_gauges[i])):
541
+ self.p_core_gauges[i][j].color = args.color
542
+ self.p_core_gauges[i][j].border_color = args.color
543
+ """
520
544
  for i in range(len(self.p_core_gauges_ext)):
521
545
  self.p_core_gauges_ext[i].color = args.color
522
546
  self.p_core_gauges_ext[i].border_color = args.color
523
-
547
+ """
524
548
  thermal_pressure = parse_thermal_pressure(powermetrics_parse)
525
549
  cpu_metrics_dict = parse_cpu_metrics(powermetrics_parse)
526
550
  gpu_metrics_dict = parse_gpu_metrics(powermetrics_parse)
@@ -577,13 +601,14 @@ class DefaultView():
577
601
  core_count += 1
578
602
  core_count = 0
579
603
  for i in cpu_metrics_dict["p_core"]:
580
- core_gauges =self.p_core_gauges if core_count < 8 else self.p_core_gauges_ext
581
- core_gauges[core_count % 8].title = "".join([
604
+ #core_gauges =self.p_core_gauges if core_count < 8 else self.p_core_gauges_ext
605
+ core_gauges = self.p_core_gauges[int(core_count / self.max_cpu_perline)]
606
+ core_gauges[core_count % self.max_cpu_perline].title = "".join([
582
607
  ("Core-" if self.p_core_count < 6 else 'C-') + str(i + 1) + " ",
583
608
  str(cpu_metrics_dict["P-Cluster" + str(i) + "_active"]),
584
609
  "%",
585
610
  ])
586
- core_gauges[core_count % 8].value = cpu_metrics_dict["P-Cluster" + str(i) + "_active"]
611
+ core_gauges[core_count % self.max_cpu_perline].value = cpu_metrics_dict["P-Cluster" + str(i) + "_active"]
587
612
  core_count += 1
588
613
 
589
614
  self.gpu_gauge.title = "".join([
@@ -766,7 +791,7 @@ class DefaultView():
766
791
  disk_read_iops = disk_metrics_dict["read_iops"]
767
792
  if disk_read_iops > self.disk_read_iops_peak:
768
793
  self.disk_read_iops_peak = disk_read_iops
769
- self.disk_read_iops_charts.title = "Read iops: "+ f'{disk_read_iops} (peak: {self.disk_read_iops_peak})'
794
+ self.disk_read_iops_charts.title = "Read iops: "+ f'{disk_read_iops}'
770
795
  if self.disk_read_iops_charts.datapoints:
771
796
  disk_read_iops_rate = int(disk_read_iops / self.disk_read_iops_peak * 100) if self.disk_read_iops_peak > 0 else 0
772
797
  else:
@@ -776,7 +801,7 @@ class DefaultView():
776
801
  disk_write_iops = disk_metrics_dict["write_iops"]
777
802
  if disk_write_iops > self.disk_write_iops_peak:
778
803
  self.disk_write_iops_peak = disk_write_iops
779
- self.disk_write_iops_charts.title = "Write iops: "+ f'{disk_write_iops} (peak: {self.disk_write_iops_peak})'
804
+ self.disk_write_iops_charts.title = "Write iops: "+ f'{disk_write_iops}'
780
805
  if self.disk_write_iops_charts.datapoints:
781
806
  disk_write_iops_rate = int(disk_read_iops / self.disk_write_iops_peak * 100) if self.disk_write_iops_peak > 0 else 0
782
807
  else:
@@ -786,7 +811,7 @@ class DefaultView():
786
811
  disk_read_bps = disk_metrics_dict["read_Bps"]
787
812
  if disk_read_bps > self.disk_read_bps_peak:
788
813
  self.disk_read_bps_peak = disk_read_bps
789
- self.disk_read_bps_charts.title = "Read : "+ f'{format_number(disk_read_bps)}/s (peak: {format_number(self.disk_read_bps_peak)}/s)'
814
+ self.disk_read_bps_charts.title = "Read : "+ f'{format_number(disk_read_bps)}/s'
790
815
  if self.disk_read_bps_charts.datapoints:
791
816
  disk_read_bps_rate = int(disk_read_bps / self.disk_read_bps_peak * 100) if self.disk_read_bps_peak > 0 else 0
792
817
  else:
@@ -796,7 +821,7 @@ class DefaultView():
796
821
  disk_write_bps = disk_metrics_dict["write_Bps"]
797
822
  if disk_write_bps > self.disk_write_bps_peak:
798
823
  self.disk_write_bps_peak = disk_write_bps
799
- self.disk_write_bps_charts.title = "Write : "+ f'{format_number(disk_write_bps)}/s (peak: {format_number(self.disk_write_bps_peak)}/s)'
824
+ self.disk_write_bps_charts.title = "Write : "+ f'{format_number(disk_write_bps)}/s'
800
825
  if self.disk_write_bps_charts.datapoints:
801
826
  disk_write_bps_rate = int(disk_write_bps / self.disk_write_bps_peak * 100) if self.disk_write_bps_peak > 0 else 0
802
827
  else:
@@ -806,7 +831,7 @@ class DefaultView():
806
831
  network_in_bps = network_metrics_dict["in_Bps"]
807
832
  if network_in_bps > self.network_in_bps_peak:
808
833
  self.network_in_bps_peak = network_in_bps
809
- self.network_in_bps_charts.title = "in : "+ f'{format_number(network_in_bps)}/s (peak: {format_number(self.network_in_bps_peak)}/s)'
834
+ self.network_in_bps_charts.title = "in : "+ f'{format_number(network_in_bps)}/s'
810
835
  if self.network_in_bps_charts.datapoints:
811
836
  network_in_bps_rate = int(network_in_bps / self.network_in_bps_peak * 100) if self.network_in_bps_peak > 0 else 0
812
837
  else:
@@ -816,23 +841,26 @@ class DefaultView():
816
841
  network_out_bps = network_metrics_dict["out_Bps"]
817
842
  if network_out_bps > self.network_out_bps_peak:
818
843
  self.network_out_bps_peak = network_out_bps
819
- self.network_out_bps_charts.title = "out : "+ f'{format_number(network_out_bps)}/s (peak: {format_number(self.network_out_bps_peak)}/s)'
844
+ self.network_out_bps_charts.title = "out : "+ f'{format_number(network_out_bps)}/s'
820
845
  if self.network_out_bps_charts.datapoints:
821
846
  network_out_bps_rate = int(network_out_bps / self.network_out_bps_peak * 100) if self.network_out_bps_peak > 0 else 0
822
847
  else:
823
848
  network_out_bps_rate = 100
824
849
  self.network_out_bps_charts.append(network_out_bps_rate)
825
850
 
851
+ self.disk_io_charts.title = ''.join([f"Disk IO (peak R:{self.disk_read_iops_peak} W:{self.disk_write_iops_peak}",
852
+ f" | R:{format_number(self.disk_read_bps_peak)}/s W:{format_number(self.disk_write_bps_peak)}/s)"
853
+ ])
854
+ self.network_io_charts.title = f"Network IO (peak in:{format_number(self.network_in_bps_peak)}/s out:{format_number(self.network_out_bps_peak)}/s)"
826
855
  self.ui.display()
827
856
 
828
857
  def get_avg(inlist):
829
858
  avg = sum(inlist) / len(inlist)
830
859
  return avg
831
860
 
832
- def main(stdscr):
861
+ def begin(stdscr):
833
862
  soc_info_dict = get_soc_info()
834
- view1 = DefaultView(soc_info_dict=soc_info_dict,args=args)
835
- clear_console()
863
+ view1 = None
836
864
  stdscr.nodelay(True)
837
865
  view = 1
838
866
  try:
@@ -844,6 +872,9 @@ def main(stdscr):
844
872
  data = data + output
845
873
  str_output = output.decode()
846
874
  if str_output.startswith('</plist>'):
875
+ if view1 is None:
876
+ view1 = DefaultView(soc_info_dict=soc_info_dict,args=args)
877
+ clear_console()
847
878
  data = data.replace(b'\x00',b'')
848
879
  powermetrics_parse = plistlib.loads(data)
849
880
  key = stdscr.getch()
@@ -882,18 +913,15 @@ def main(stdscr):
882
913
 
883
914
  return
884
915
 
885
-
886
- if __name__ == "__main__":
916
+ def main():
917
+ global powermetrics_process
887
918
  print(f"\n{version} - enhanced MAC Performance monitoring CLI tool for Apple Silicon")
888
919
  print("You can update macpm by running `pip install macpm --upgrade`")
889
920
  print("Get help at `https://github.com/visualcjy/macpm`")
890
921
  print("P.S. You are recommended to run macpm with `sudo macpm`\n")
891
922
  print("\n[1/3] Loading macpm\n")
892
- print("\033[?25l")
893
- #global powermetrics_process
894
-
895
923
  print("\n[2/3] Starting powermetrics process\n")
896
-
924
+ pause = os.popen("sudo echo").read()
897
925
  command = " ".join([
898
926
  "sudo nice -n",
899
927
  str(10),
@@ -906,9 +934,14 @@ if __name__ == "__main__":
906
934
  powermetrics_process = subprocess.Popen(command.split(" "), stdin=PIPE, stdout=PIPE)
907
935
 
908
936
  print("\n[3/3] Waiting for first reading...\n")
909
-
910
- curses.wrapper(main)
937
+ print("\033[?25l")
938
+ curses.wrapper(begin)
911
939
  print("\033[?25h")
940
+
941
+ if __name__ == "__main__":
942
+
943
+ main()
944
+
912
945
  try:
913
946
  powermetrics_process.terminate()
914
947
  print("Successfully terminated powermetrics process")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: macpm
3
- Version: 0.15
3
+ Version: 0.22
4
4
  Summary: Performance monitoring CLI tool for Apple Silicon
5
5
  Home-page: https://github.com/visualcjy/macpm
6
6
  Author: Jinyu Chen
@@ -4,7 +4,7 @@ long_description = 'Performance monitoring CLI tool for Apple Silicon'
4
4
 
5
5
  setup(
6
6
  name='macpm',
7
- version='0.15',
7
+ version='0.22',
8
8
  author='Jinyu Chen',
9
9
  author_email='visualcjy@mail.com',
10
10
  url='https://github.com/visualcjy/macpm',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes