From eabbe8108092631eef06d8bad25e49aaf89cee00 Mon Sep 17 00:00:00 2001 From: DVR Date: Fri, 5 Nov 2021 04:03:29 -0400 Subject: [PATCH] amdgpu support using radeontop & gpu-ls --- sysmontask/gpu.py | 283 ++++++++++++++++++++++++++++--------- sysmontask/sidepane.py | 6 +- sysmontask/sysmontask.py | 16 ++- sysmontask/sysmontask.spec | 40 ++++++ 4 files changed, 273 insertions(+), 72 deletions(-) create mode 100644 sysmontask/sysmontask.spec diff --git a/sysmontask/gpu.py b/sysmontask/gpu.py index 0e28689..d54fddf 100644 --- a/sysmontask/gpu.py +++ b/sysmontask/gpu.py @@ -3,7 +3,7 @@ # gi.require_version("Gtk", "3.24") from gi.repository import Gtk as g -from os import popen +from os import popen, _exit from xml.etree.ElementTree import fromstring try: @@ -16,6 +16,8 @@ else: from sysmontask import files_dir +gpu_glade = '/gpu.glade' + @GtkTemplate(ui=files_dir+'/gpu.glade') class gpuTabWidget(g.ScrolledWindow): @@ -69,7 +71,7 @@ def givedata(self,secondself): self.gpuvramArray=secondself.gpuVramArray self.gpuencodingArray=secondself.gpuEncodingArray self.gpudecodingArray=secondself.gpuDecodingArray - self.gputotalvram=int(secondself.totalvram[:-3]) + self.gputotalvram=int(secondself.totalvram) self.secondself=secondself @GtkTemplate.Callback @@ -159,6 +161,7 @@ def gpuutildrawarea_draw(self,dr,cr): @GtkTemplate.Callback def gpuencodingdrawarea_draw(self,dr,cr): + if self.isAMDgpu ==1: return #print("idsaf") cr.set_line_width(2) @@ -228,6 +231,7 @@ def gpuencodingdrawarea_draw(self,dr,cr): @GtkTemplate.Callback def gpudecodingdrawarea_draw(self,dr,cr): + if self.isAMDgpu ==1: return #print("idsaf") cr.set_line_width(2) @@ -365,6 +369,7 @@ def gpuvramdrawarea_draw(self,dr,cr): def gpuinit(self): ##logic to determine the number of gpus but for now i just focusing on one gpu self.isNvidiagpu=1 + self.isAMDgpu = 0 self.gpuUtilArray=[0]*100 self.gpuEncodingArray=[0]*100 self.gpuDecodingArray=[0]*100 @@ -377,7 +382,6 @@ def gpuinit(self): print('okk') self.gpuWidget=gpuTabWidget() self.performanceStack.add_titled(self.gpuWidget,f'page{self.stack_counter}','GPU') - self.gpuName=gpuinfoRoot.find('gpu').find('product_name').text self.gpuWidget.gpuinfolabel.set_text(self.gpuName) self.totalvram=gpuinfoRoot.find('gpu').find('fb_memory_usage').find('total').text @@ -395,77 +399,230 @@ def gpuinit(self): except Exception as e: print('no nvidia gpu found',e) self.isNvidiagpu=0 - - -def gpuUpdate(self): - try: - p=popen('nvidia-smi -q -x') - xmlout=p.read() - p.close() - gpuinfoRoot=fromstring(xmlout) - self.vramused=gpuinfoRoot.find('gpu').find('fb_memory_usage').find('used').text - self.gpuutil=gpuinfoRoot.find('gpu').find('utilization').find('gpu_util').text - self.gpuWidget.gpuutilisationlabelvalue.set_text(self.gpuutil) - self.gpuWidget.gpuvramusagelabelvalue.set_text(f'{self.vramused[:-3]}/{self.totalvram}') - - gpu_temp=gpuinfoRoot.find('gpu').find('temperature').find('gpu_temp').text - if gpu_temp[-1]=='C': - gpu_temp =f'{gpu_temp[:-1]}°C' - - self.gpuWidget.gputemplabelvalue.set_text(gpu_temp) - self.gpuWidget.gpushaderspeedlabelvalue.set_text(gpuinfoRoot.find('gpu').find('clocks').find('graphics_clock').text) - self.gpuWidget.gpuvramspeedlabelvalue.set_text(gpuinfoRoot.find('gpu').find('clocks').find('mem_clock').text) - - ############ int conv bug solve ###################### - gpu_enc=gpuinfoRoot.find('gpu').find('utilization').find('encoder_util').text + self.isAMDgpu = 1 + global gpu_glade + gpu_glade = '/amdgpu.glade' try: - gpu_enc=int(gpu_enc[:-1]) - except Exception: - gpu_enc=0 + p=popen('radeontop -l 1 -d -') + csvout=p.read() + p.close() + gpuinfoRoot = csvout.split(',') + #remove extraneous output + gpuinfoRoot = gpuinfoRoot[2:] + #strip leading space + gpuinfoRoot = [data.lstrip() for data in gpuinfoRoot] + #convert to dictionary + keys = [key.split(" ", 1)[0] for key in gpuinfoRoot] + values = [value.split(" ", 1)[1] for value in gpuinfoRoot] + gpuInfoDict = dict(zip(keys, values)) + #create subdictionaries. + for key in gpuInfoDict: + if ' ' in gpuInfoDict[key]: + value0 = gpuInfoDict[key].split(' ', 1)[0].rstrip() + value1 = gpuInfoDict[key].split(' ', 1)[1].rstrip() + gpuInfoDict[key] = [value0, value1] + print(gpuInfoDict) + #get gpu name using gpu-ls util.. + p=popen('gpu-ls --short') + textout=p.readlines() + p.close() + for line in textout: + if "Decoded Device ID" in line: + gpuname = line.split("ID:")[1].lstrip().rstrip() + print(gpuname) + self.gpuWidget=gpuTabWidget() + self.performanceStack.add_titled(self.gpuWidget,f'page{self.stack_counter}','GPU') + self.gpuName=gpuname + self.gpuWidget.gpuinfolabel.set_text(self.gpuName) + self.currentvrammb = (float(gpuInfoDict["vram"][1][:-2])) + self.totalvram = str(int((100 * self.currentvrammb) / float(gpuInfoDict["vram"][0][:-1]))) + print(self.totalvram) + self.gpuWidget.gpuvramlabelvalue.set_text(self.totalvram) + + setattr(self.gpuWidget, 'isAMDgpu', self.isAMDgpu) + #not sure what driver version is + self.gpuWidget.gpudriverlabelvalue.set_text("") + + #not sure what equivalent cuda core to AMD thing is. + self.gpuWidget.gpucudalabelvalue.set_text("") + + #not sure how to get this yet + self.gpuWidget.gpumaxspeedlabelvalue.set_text("") + + #think this fits + self.gpuWidget.gpuvrammaxspeedlabelvalue.set_text(gpuInfoDict["mclk"][1]) + + # For lookup of devices and its assigned stack page numbers + self.device_stack_page_lookup[self.gpuName]=self.stack_counter + self.stack_counter+=1 + + self.gpuWidget.givedata(self) + except Exception as e: + print('No Amd, or Nvidia GPU found.',e) + self.isNvidiagpu=0 + self.isAMDgpu = 0 - gpu_dec=gpuinfoRoot.find('gpu').find('utilization').find('decoder_util').text +def gpuUpdate(self): + if self.isNvidiagpu == 1: try: - gpu_dec=int(gpu_dec[:-1]) - except Exception: - gpu_dec=0 - - if self.update_graph_direction: - self.gpuUtilArray.pop(0) - try: - self.gpuUtilArray.append(int(self.gpuutil[:-1])) - except Exception: - self.gpuUtilArray.append(0) - - self.gpuVramArray.pop(0) + p=popen('nvidia-smi -q -x') + xmlout=p.read() + p.close() + gpuinfoRoot=fromstring(xmlout) + self.vramused=gpuinfoRoot.find('gpu').find('fb_memory_usage').find('used').text + self.gpuutil=gpuinfoRoot.find('gpu').find('utilization').find('gpu_util').text + self.gpuWidget.gpuutilisationlabelvalue.set_text(self.gpuutil) + self.gpuWidget.gpuvramusagelabelvalue.set_text(f'{self.vramused[:-3]}/{self.totalvram}') + + gpu_temp=gpuinfoRoot.find('gpu').find('temperature').find('gpu_temp').text + if gpu_temp[-1]=='C': + gpu_temp =f'{gpu_temp[:-1]}°C' + + self.gpuWidget.gputemplabelvalue.set_text(gpu_temp) + self.gpuWidget.gpushaderspeedlabelvalue.set_text(gpuinfoRoot.find('gpu').find('clocks').find('graphics_clock').text) + self.gpuWidget.gpuvramspeedlabelvalue.set_text(gpuinfoRoot.find('gpu').find('clocks').find('mem_clock').text) + + ############ int conv bug solve ###################### + gpu_enc=gpuinfoRoot.find('gpu').find('utilization').find('encoder_util').text try: - self.gpuVramArray.append(int(gpuinfoRoot.find('gpu').find('fb_memory_usage').find('used').text[:-3])) + gpu_enc=int(gpu_enc[:-1]) except Exception: - self.gpuVramArray.append(0) + gpu_enc=0 - self.gpuEncodingArray.pop(0) - self.gpuEncodingArray.append(gpu_enc) + gpu_dec=gpuinfoRoot.find('gpu').find('utilization').find('decoder_util').text - self.gpuDecodingArray.pop(0) - self.gpuDecodingArray.append(gpu_dec) - else: - self.gpuUtilArray.pop() try: - self.gpuUtilArray.insert(0,int(self.gpuutil[:-1])) + gpu_dec=int(gpu_dec[:-1]) except Exception: - self.gpuUtilArray.insert(0,0) - - self.gpuVramArray.pop() + gpu_dec=0 + + if self.update_graph_direction: + self.gpuUtilArray.pop(0) + try: + self.gpuUtilArray.append(int(self.gpuutil[:-1])) + except Exception: + self.gpuUtilArray.append(0) + + self.gpuVramArray.pop(0) + try: + self.gpuVramArray.append(int(gpuinfoRoot.find('gpu').find('fb_memory_usage').find('used').text[:-3])) + except Exception: + self.gpuVramArray.append(0) + + self.gpuEncodingArray.pop(0) + self.gpuEncodingArray.append(gpu_enc) + + self.gpuDecodingArray.pop(0) + self.gpuDecodingArray.append(gpu_dec) + else: + self.gpuUtilArray.pop() + try: + self.gpuUtilArray.insert(0,int(self.gpuutil[:-1])) + except Exception: + self.gpuUtilArray.insert(0,0) + + self.gpuVramArray.pop() + try: + self.gpuVramArray.insert(0,int(gpuinfoRoot.find('gpu').find('fb_memory_usage').find('used').text[:-3])) + except Exception: + self.gpuVramArray.insert(0,0) + + self.gpuEncodingArray.pop() + self.gpuEncodingArray.insert(0,gpu_enc) + self.gpuDecodingArray.pop() + self.gpuDecodingArray.insert(0,gpu_dec) + + self.gpuWidget.givedata(self) + except Exception as e: + print(f"some error in nvidia gpu updata: {e}") + + if self.isAMDgpu == 1: + try: + p=popen('radeontop -l 1 -d -') + csvout=p.read() + p.close() + gpuinfoRoot = csvout.split(',') + #remove extraneous output + gpuinfoRoot = gpuinfoRoot[2:] + #strip leading space + gpuinfoRoot = [data.lstrip() for data in gpuinfoRoot] + #convert to dictionary + keys = [key.split(" ", 1)[0] for key in gpuinfoRoot] + values = [value.split(" ", 1)[1] for value in gpuinfoRoot] + gpuInfoDict = dict(zip(keys, values)) + #create subdictionaries. + for key in gpuInfoDict: + if ' ' in gpuInfoDict[key]: + value0 = gpuInfoDict[key].split(' ', 1)[0].rstrip() + value1 = gpuInfoDict[key].split(' ', 1)[1].rstrip() + gpuInfoDict[key] = [value0, value1] + + self.vramused=gpuInfoDict["vram"][1][:-2] + self.gpuutil=gpuInfoDict["gpu"] + self.gpuWidget.gpuutilisationlabelvalue.set_text(self.gpuutil) + self.gpuWidget.gpuvramusagelabelvalue.set_text(f'{self.vramused}/{self.totalvram}') + + + p=popen('gpu-ls') + textout=p.readlines() + p.close() + for line in textout: + if "Current Temps (C):" in line: + curTempDict = line.split("(C):")[1].lstrip() + gpu_temp = curTempDict.split(':')[1][:-2].lstrip() + self.gpuWidget.gputemplabelvalue.set_text(gpu_temp) + + + + self.gpuWidget.gpushaderspeedlabelvalue.set_text(gpuInfoDict["sclk"][1]) + self.gpuWidget.gpuvramspeedlabelvalue.set_text(gpuInfoDict["mclk"][1]) + + ############ int conv bug solve ###################### try: - self.gpuVramArray.insert(0,int(gpuinfoRoot.find('gpu').find('fb_memory_usage').find('used').text[:-3])) + gpu_enc=gpuinfoRoot.find('gpu').find('utilization').find('encoder_util').text + gpu_enc=int(gpu_enc[:-1]) except Exception: - self.gpuVramArray.insert(0,0) + gpu_enc=0 - self.gpuEncodingArray.pop() - self.gpuEncodingArray.insert(0,gpu_enc) - self.gpuDecodingArray.pop() - self.gpuDecodingArray.insert(0,gpu_dec) - self.gpuWidget.givedata(self) - except Exception as e: - print(f"some error in gpu updata: {e}") \ No newline at end of file + try: + gpu_dec=gpuinfoRoot.find('gpu').find('utilization').find('decoder_util').text + gpu_dec=int(gpu_dec[:-1]) + except Exception: + gpu_dec=0 + + self.gpuutil = int(float(self.gpuutil[:-1])) + #self.vramused = 0 + self.vramused = int(float(self.vramused)) + print(self.vramused) + + if self.update_graph_direction: + self.gpuUtilArray.pop(0) + self.gpuUtilArray.append(self.gpuutil) + + self.gpuVramArray.pop(0) + self.gpuVramArray.append(self.vramused) + + #self.gpuEncodingArray.pop(0) + #self.gpuEncodingArray.append(gpu_enc) + + #self.gpuDecodingArray.pop(0) + #self.gpuDecodingArray.append(gpu_dec) + else: + self.gpuUtilArray.pop() + self.gpuUtilArray.insert(0, self.gpuutil) + + self.gpuVramArray.pop() + self.gpuVramArray.insert(0, self.vramused) + + #self.gpuEncodingArray.pop() + #self.gpuEncodingArray.insert(0,gpu_enc) + #self.gpuDecodingArray.pop() + #self.gpuDecodingArray.insert(0,gpu_dec) + + self.gpuWidget.givedata(self) + print(self.gpuVramArray) + print("REACHED AMD GPU UPDATE!") + except Exception as e: + print(f"some error in amd gpu updata: {e}") \ No newline at end of file diff --git a/sysmontask/sidepane.py b/sysmontask/sidepane.py index fbcd41b..9fea441 100644 --- a/sysmontask/sidepane.py +++ b/sysmontask/sidepane.py @@ -580,7 +580,7 @@ def sidepaneinit(self): self.stack_switcher_buttons[button_counter]=self.netSidepaneWidgetList[i].net_switcher_button button_counter+=1 - if(self.isNvidiagpu==1): + if(self.isNvidiagpu==1 or self.isAMDgpu==1): self.gpuSidePaneWidget=gpuSidepaneWidget() self.sidepaneBox.pack_start(self.gpuSidePaneWidget,True,True,0) self.gpuSidePaneWidget.gpusidepanetextlabel.set_text(f'{self.gpuName.split()[-2]}{self.gpuName.split()[-1]}') @@ -618,9 +618,9 @@ def sidePaneUpdate(self): except Exception as e: print(f"some error in netsidepane update {e}") - if(self.isNvidiagpu==1): + if(self.isNvidiagpu==1 or self.isAMDgpu==1): try: - self.gpuSidePaneWidget.gpusidepanelabelvalue.set_text(self.gpuutil) + self.gpuSidePaneWidget.gpusidepanelabelvalue.set_text(str(self.gpuutil)) self.gpuSidePaneWidget.givedata(self) except Exception as e: print(f"some error in gpusidepane update {e}") \ No newline at end of file diff --git a/sysmontask/sysmontask.py b/sysmontask/sysmontask.py index f194e3a..c8400aa 100755 --- a/sysmontask/sysmontask.py +++ b/sysmontask/sysmontask.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +import threading + ############ container missing error in some distro ############# from gi import require_version require_version("Gtk", "3.0") @@ -282,7 +284,7 @@ def post_init(self): 'cpu':'cpu', 'memory':'memory', } - if self.isNvidiagpu: + if self.isNvidiagpu or self.isAMDgpu: self.grouping_for_color_profile[self.gpuName]='gpu' for i in self.disklist: self.grouping_for_color_profile[i]='disk' @@ -539,7 +541,7 @@ def on_refresh_activate(self,menuitem,data=None): self.stack_counter=2 # Destroying the all the except CPU and Memory - if(self.isNvidiagpu==1): + if(self.isNvidiagpu==1 or self.isAMDgpu==1): g.Widget.destroy(self.gpuWidget) g.Widget.destroy(self.gpuSidePaneWidget) for i in range(0,self.numOfDisks): @@ -685,8 +687,10 @@ def updater(self): self.disktabUpdate() if len(self.netNameList)!=0: self.netTabUpdate() - if(self.isNvidiagpu==1): - self.gpuTabUpdate() + + if(self.isNvidiagpu==1 or self.isAMDgpu==1): + threading.Thread(target=lambda: self.gpuTabUpdate()).start() + self.sidepaneUpdate() # Calling drawing methods putting them into the queue to draw for each component. @@ -704,7 +708,7 @@ def updater(self): for i in range(0,self.numOfNets): g.Widget.queue_draw(self.netWidgetList[i].netdrawarea) - if(self.isNvidiagpu==1): + if(self.isNvidiagpu==1 or self.isAMDgpu==1): g.Widget.queue_draw(self.gpuWidget.gpuutildrawarea) g.Widget.queue_draw(self.gpuWidget.gpuvramdrawarea) g.Widget.queue_draw(self.gpuWidget.gpuencodingdrawarea) @@ -718,7 +722,7 @@ def updater(self): g.Widget.queue_draw(self.diskSidepaneWidgetList[i].disksidepanedrawarea) for i in range(self.numOfNets): g.Widget.queue_draw(self.netSidepaneWidgetList[i].netsidepanedrawarea) - if(self.isNvidiagpu==1): + if(self.isNvidiagpu==1 or self.isAMDgpu==1): g.Widget.queue_draw(self.gpuSidePaneWidget.gpusidepanedrawarea) # Returning True to run periodically diff --git a/sysmontask/sysmontask.spec b/sysmontask/sysmontask.spec new file mode 100644 index 0000000..95c6b89 --- /dev/null +++ b/sysmontask/sysmontask.spec @@ -0,0 +1,40 @@ +# -*- mode: python ; coding: utf-8 -*- + + +block_cipher = None + + +a = Analysis(['sysmontask.py'], + pathex=['/home/daniel/SysMonTask/sysmontask'], + binaries=[], + datas=[], + hiddenimports=[], + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) +pyz = PYZ(a.pure, a.zipped_data, + cipher=block_cipher) + +exe = EXE(pyz, + a.scripts, + a.binaries, + a.zipfiles, + a.datas, + [], + name='sysmontask', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=True, + disable_windowed_traceback=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None )