From d780d5e0bbb7ffa6b887f986d980b9a800d096a8 Mon Sep 17 00:00:00 2001 From: Peuuuur-Noel Date: Sat, 4 May 2024 22:17:32 +0000 Subject: [PATCH 1/8] - Use websocket (nchan) instead of ajax polling to refresh data in dashboard - All apps usage statuses are no longer sent, only active apps --- .../plugins/gpustat/GPUStatSettings.page | 33 ++- .../emhttp/plugins/gpustat/css/style.css | 4 - .../gpustat/gpustatusmovablemulti.page | 254 ++++++++---------- .../emhttp/plugins/gpustat/gpustatusmulti.php | 48 +--- .../emhttp/plugins/gpustat/lib/Nvidia.php | 36 +-- .../emhttp/plugins/gpustat/nchan/gpustat | 92 +++++++ .../plugins/gpustat/scripts/gpustatmulti.js | 98 +++---- 7 files changed, 305 insertions(+), 260 deletions(-) create mode 100644 src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page b/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page index dce6607..dc621f9 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page @@ -64,23 +64,23 @@ Title="GPU Statistics" $json_array[$pciid]['vendor'] = $gpus[$gpupciid]['vendor'] ; $json_array[$pciid]['guid'] = $gpus[$gpupciid]['guid'] ; } - } else { + } else { $json_array[$pciid]['id'] = "None"; $json_array[$pciid]['model'] = "None"; $json_array[$pciid]['vendor'] = "None"; $json_array[$pciid]['guid'] = "None"; } $val["MULTIGPUJSON"] = urlencode(json_encode($json_array)) ; - if (isset($val['MULTIGPU'])) { + if (isset($val['MULTIGPU'])) { if($val['MULTIGPU'] != "") $val['MULTIGPU'] = implode("," , $val['MULTIGPU']) ; } else $val['MULTIGPU'] = "" ; } - + save_ini_file("gpustat.cfg", $val) ; } - $cfg = $gpustat_cfg = parse_plugin_cfg("gpustat", true); - $gpustat_inventory = true; + $cfg = $gpustat_cfg = parse_plugin_cfg("gpustat", true); + $gpustat_inventory = true; $multi_enable=version_compare(parse_ini_file('/etc/unraid-version')['version'],'6.12.0-beta5', '>') ; @@ -90,8 +90,8 @@ Title="GPU Statistics" include_once './plugins/gpustat/gpustatus.php'; } - - + + $multi_enable=version_compare(parse_ini_file('/etc/unraid-version')['version'],'6.12.0-beta5', '>') ; if (count($_POST)) { @@ -99,9 +99,16 @@ Title="GPU Statistics" if ($_POST['#apply'] == "_(Apply)_") { array_map(function($k, $v) use (&$cfg) { if($k[0] != "#") $cfg[$k] = $v; }, array_keys($_POST), $_POST ); save_cfg($cfg,$gpustat_data) ; - $gpustat_cfg = parse_plugin_cfg("gpustat", true); - unset($_POST) ; - } + + // Restart nchan gpustat if not running when refresh setting set to Yes + $pid = exec('pgrep gpustat'); + if (!$pid && $_POST['UIREFRESH'] == '1' && $gpustat_cfg['UIREFRESH'] != '1') { + exec('/usr/local/emhttp/plugins/gpustat/nchan/gpustat &>/dev/null &'); + } + + $gpustat_cfg = parse_plugin_cfg("gpustat", true); + unset($_POST); + } } ?> @@ -142,8 +149,8 @@ Unit ID for Dashboard: Unit ID for Dashboard(Multiple): : +

AMD Specific

diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css b/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css index ce85522..66981c4 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css @@ -31,10 +31,6 @@ span.gpu { display: inline-block; } -span.gpu-img-span { - display: none; -} - .gpu-image { padding-left: 8px; height: 32px; diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page index 49329ff..0a906f7 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page @@ -1,6 +1,7 @@ Menu="Dashboard:0" Icon="gpustat.png" Cond="version_compare(parse_ini_file('/etc/unraid-version')['version'],'6.12.0-beta5', '>')" +Nchan="gpustat" --- $gpu) { $gpu_nv = $gpu_intel = $gpu_amd = $gpu_unknown = false; @@ -85,37 +81,32 @@ foreach ($multigpus as $id=>$gpu) { } if ($gpus_selected > 1) $gpu_tag = $i ; else $gpu_tag = "" ; - $stats = "
_(GPU".$gpu_tag.")_
Load: " ; + $stats = "
_(GPU".$gpu_tag.")_
Load: " ; if ($gpu_nv || $gpu_amd) { - if ($gpustat_cfg['DISPTEMP']) $stats .= " Temperature: " ; + if ($gpustat_cfg['DISPTEMP']) $stats .= " Temperature: " ; } - if ($gpu_nv && $gpustat_cfg['DISPSESSIONS']) $stats .=" Processes: "; + if ($gpu_nv && $gpustat_cfg['DISPSESSIONS']) $stats .=" Processes: "; $stats .= "

" ; - $layout = GPULayout($i, $gpu["vendor"],$gpustat_cfg) ; + $layout = GPULayout($gpu["vendor"],$gpustat_cfg) ; $mytiles[$pluginname.$k]['column'.$j] = << + $stats _(Vendor)__(Device)_ $layout - - _(GPU not available bound to VFIO or inuse in a VM.)_ + + _(GPU not available bound to VFIO or inuse in a VM.)_ EOT; - $multigpus[$id]["panel"] = $i ; $i++ ; #GPU Number $j++ ; #Default Column if ($j >3) { $j=1 ; $k++ ;} #Plugin name in array. Only 3 Dashboards per name. } -function GPULayout($count,$vendor,$gpustat_cfg) { - $apps = [ - 'plex', 'jellyfin', 'handbrake', 'emby', 'tdarr', 'unmanic', 'dizquetv', 'ersatztv', - 'fileflows', 'frigate', 'deepstack', 'nsfminer', 'shinobipro', 'foldinghome','threadfin', 'codeproject', 'compreface', -]; +function GPULayout($vendor,$gpustat_cfg) { $gpu_nv = $gpu_intel = $gpu_amd = $gpu_unknown = false; switch ($vendor) { case "nvidia": @@ -134,262 +125,249 @@ $gpu_nv = $gpu_intel = $gpu_amd = $gpu_unknown = false; } $page_render = '' ; - $page_render .= " " ; + $page_render .= " " ; - # No GPU Set + # No GPU Set - if ($gpu_unknown) $page_render .= "_(No GPUs selected - Select GPU(s) in GPUStat settings page and apply.)_" ; + if ($gpu_unknown) $page_render .= "_(No GPUs selected - Select GPU(s) in GPUStat settings page and apply.)_" ; # Nvidia GPUs if ($gpu_nv) { if($gpustat_cfg['DISPPCIUTIL']) { - $page_render .= "  PCIe Gen (Max):  ()" ; - $page_render .= "  Lanes (Max):  ()" ; + $page_render .= "  PCIe Gen (Max):  ()" ; + $page_render .= "  Lanes (Max):  ()" ; } if ($gpu_nv) { - $page_render .= "_(Load - Memory)_" ; - $page_render .= "0%
" ; + $page_render .= "_(Load - Memory)_" ; + $page_render .= "0%
" ; if($gpustat_cfg['DISPMEMUTIL']) { - $page_render .= "0%
" ; + $page_render .= "0%
" ; } $page_render .= "" ; } if($gpustat_cfg['DISPENCDEC']) { - $page_render .= "_(Encoder - Decoder)_" ; - $page_render .= "0%
" ; - $page_render .= "0%
" ; + $page_render .= "_(Encoder - Decoder)_" ; + $page_render .= "0%
" ; + $page_render .= "0%
" ; $page_render .= "" ; } - + if($gpustat_cfg['DISPCLOCKS']) { - $page_render .= "_(GPU - Memory (MHz))_" ; - $page_render .= "0%
" ; - $page_render .= "0%
" ; + $page_render .= "_(GPU - Memory (MHz))_" ; + $page_render .= "0%
" ; + $page_render .= "0%
" ; $page_render .= "" ; } if($gpustat_cfg['DISPFAN'] || $gpustat_cfg['DISPPWRDRAW']) { - $page_render .= "_(Fan - Power)_" ; + $page_render .= "_(Fan - Power)_" ; if($gpustat_cfg['DISPFAN']) { - $page_render .= "0%
" ; + $page_render .= "0%
" ; } if($gpustat_cfg['DISPPWRDRAW']) { - $page_render .= "0%
" ; + $page_render .= "0%
" ; } $page_render .= "" ; } if($gpustat_cfg['DISPPCIUTIL']) { - $page_render .= "_(PCI Bus Rx/Tx (MB/s))_" ; - $page_render .= "0%
" ; - $page_render .= "0%
" ; + $page_render .= "_(PCI Bus Rx/Tx (MB/s))_" ; + $page_render .= "0%
" ; + $page_render .= "0%
" ; $page_render .= "" ; } if($gpustat_cfg['DISPTHROTTLE'] || $gpustat_cfg['DISPPWRSTATE']) { - $page_render .= "_(Power State - Throttling)_" ; + $page_render .= "_(Power State - Throttling)_" ; if($gpustat_cfg['DISPPWRSTATE']) { - $page_render .= "" ; + $page_render .= "" ; } if($gpustat_cfg['DISPTHROTTLE']) { - $page_render .= " " ; + $page_render .= " " ; } $page_render .= "" ; } - + if($gpustat_cfg['DISPSESSIONS']) { - $page_render .= "_(Active Apps)_" ; - foreach($apps as $app) { - $page_render .= "" ; - $page_render .= "" ; - $page_render .= "" ; - } - $page_render .= "" ; - } + $page_render .= "_(Active Apps)_" ; + } } if ($gpu_intel) { if($gpustat_cfg['DISP3DRENDER']) { - $page_render .= "_(3D Render Load)_" ; - $page_render .= "0%
" ; - $page_render .= "
" ; + $page_render .= "_(3D Render Load)_" ; + $page_render .= "0%
" ; + $page_render .= "
" ; } if($gpustat_cfg['DISPBLITTER']) { - $page_render .="_(Blitter Load)_" ; - $page_render .="
" ; - $page_render .="
" ; + $page_render .="_(Blitter Load)_" ; + $page_render .="
" ; + $page_render .="
" ; } if($gpustat_cfg['DISPVIDEO']) { - $page_render .="_(Video Load)_" ; - $page_render .="
" ; - $page_render .="
" ; + $page_render .="_(Video Load)_" ; + $page_render .="
" ; + $page_render .="
" ; } if($gpustat_cfg['DISPVIDENH']) { - $page_render .= "_(Video Enhance Load)_" ; - $page_render .="
" ; - $page_render .="
" ; + $page_render .= "_(Video Enhance Load)_" ; + $page_render .="
" ; + $page_render .="
" ; } - if($gpustat_cfg['DISPPWRDRAW']) { - $page_render .="_(Power Draw)_" ; - $page_render .="
" ; - $page_render .="
" ; + if($gpustat_cfg['DISPPWRDRAW']) { + $page_render .="_(Power Draw)_" ; + $page_render .="
" ; + $page_render .="
" ; } if($gpustat_cfg['DISPPCIUTIL']) { - $page_render .="_(IMC Bus Utilization)_" ; - $page_render .="Receive:   Transmit: " ; + $page_render .="_(IMC Bus Utilization)_" ; + $page_render .="Receive:   Transmit: " ; } if($gpustat_cfg['DISPCLOCKS']) { - $page_render .="_(GPU Clock (MHz))_" ; - $page_render .="" ; + $page_render .="_(GPU Clock (MHz))_" ; + $page_render .="" ; } if($gpustat_cfg['DISPINTERRUPT']) { - $page_render .="_(Interrupts/Sec)_" ; - $page_render .="" ; + $page_render .="_(Interrupts/Sec)_" ; + $page_render .="" ; } - + } - // AMD GPUs + // AMD GPUs if ($gpu_amd) { - $page_render .="_(GPU Load)_" ; - $page_render .="0%
" ; - + $page_render .="_(GPU Load)_" ; + $page_render .="0%
" ; + if($gpustat_cfg['DISPGFXTRANS'] || $gpustat_cfg['DISPMEMUTIL']) { - $page_render .= "_(Translate - Memory (MB))_" ; + $page_render .= "_(Translate - Memory (MB))_" ; if($gpustat_cfg['DISPGFXTRANS']) { - $page_render .= "0%
" ; - $page_render .= "
" ; + $page_render .= "0%
" ; + $page_render .= "
" ; } if($gpustat_cfg['DISPMEMUTIL']) { - $page_render .= "0%
" ; - $page_render .= "
"; + $page_render .= "0%
" ; + $page_render .= "
"; } $page_render .= "" ; } if($gpustat_cfg['DISPEVENT'] || $gpustat_cfg['DISPVERTEX']) { - $page_render .= "_(Event - Vertex (MB))_" ; + $page_render .= "_(Event - Vertex (MB))_" ; if($gpustat_cfg['DISPEVENT']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; } if($gpustat_cfg['DISPVERTEX']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; } } if($gpustat_cfg['DISPTEXTURE'] || $gpustat_cfg['DISPSEQUENCER']) { - $page_render .= "_(Texture - Sequencer)_" ; + $page_render .= "_(Texture - Sequencer)_" ; if($gpustat_cfg['DISPTEXTURE']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; } if($gpustat_cfg['DISPSEQUENCER']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; } $page_render .= "" ; } if($gpustat_cfg['DISPSHADEREXP'] || $gpustat_cfg['DISPSHADERINTER']) { - $page_render .= "_(Shader Export - Interpol)_" ; + $page_render .= "_(Shader Export - Interpol)_" ; if($gpustat_cfg['DISPSHADEREXP']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; } if($gpustat_cfg['DISPSHADERINTER']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; } $page_render .= "" ; } if($gpustat_cfg['DISPSCANCON'] || $gpustat_cfg['DISPPRIMASSEM']) { - $page_render .= "_(Scan Conv - Prim Assem)_" ; + $page_render .= "_(Scan Conv - Prim Assem)_" ; if($gpustat_cfg['DISPSCANCON']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; } if($gpustat_cfg['DISPPRIMASSEM']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; } $page_render .= "" ; } if($gpustat_cfg['DISPDEPTHBLK'] || $gpustat_cfg['DISPCOLORBLK']) { - $page_render .= "_(Blocks: Depth - Color)_" ; - if($gpustat_cfg['DISPDEPTHBLK']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "_(Blocks: Depth - Color)_" ; + if($gpustat_cfg['DISPDEPTHBLK']) { + $page_render .= "
" ; + $page_render .= "
" ; } if($gpustat_cfg['DISPCOLORBLK']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; } $page_render .= "" ; } if($gpustat_cfg['DISPFAN'] || $gpustat_cfg['DISPPWRDRAW']) { - $page_render .= "_(Fan - Power)_" ; + $page_render .= "_(Fan - Power)_" ; if($gpustat_cfg['DISPFAN']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; } if($gpustat_cfg['DISPPWRDRAW']) { - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; } - + } if($gpustat_cfg['DISPCLOCKS']) { - $page_render .= "_(Clocks: Shader - Mem (GHz))_" ; - $page_render .= "
" ; - $page_render .= "
" ; - $page_render .= "
" ; - $page_render .= "
" ; + $page_render .= "_(Clocks: Shader - Mem (GHz))_" ; + $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; + $page_render .= "
" ; $page_render .= "" ; } } - return($page_render) ; + return($page_render) ; } - ?> - +const gpustat_ws = new NchanSubscriber('/sub/gpustat'); +gpustat_ws.on('message', (data) => { + parseStats(JSON.parse(data)); +}); +gpustat_ws.start(); + \ No newline at end of file diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmulti.php b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmulti.php index b58ad0b..e6da40a 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmulti.php +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmulti.php @@ -30,13 +30,11 @@ include 'lib/Nvidia.php'; include 'lib/Intel.php'; include 'lib/AMD.php'; -include 'lib/Error.php'; use gpustat\lib\AMD; use gpustat\lib\Main; use gpustat\lib\Nvidia; use gpustat\lib\Intel; -use gpustat\lib\Error; if (!isset($gpustat_cfg)) { $gpustat_cfg = Main::getSettings(); @@ -45,50 +43,12 @@ // $gpustat_inventory should be set if called from settings page code if (isset($gpustat_inventory) && $gpustat_inventory) { $gpustat_cfg['inventory'] = true; + // Settings page looks for $gpustat_data specifically -- inventory all supported GPU types $gpustat_data = array_merge((new Nvidia($gpustat_cfg))->getInventorym(), (new Intel($gpustat_cfg))->getInventory(), (new AMD($gpustat_cfg))->getInventorym()); - file_put_contents("/tmp/gpuinv",json_encode($gpustat_data)) ; -} else { - - -$array=json_decode($_GET['gpus'],true) ; + // Test data + // $gpustat_data = array_merge($gpustat_data, json_decode('{"0000:00:02.0": {"id": "00:02.0","model": "AlderLake-S GT1","vendor": "intel","guid": "GPU-94118c02-132c-45bb-a114-df6f24902d5d"},"0000:09:00.0": {"id": "09:00.0","model": "DG2 [Arc A770]","vendor": "intel","guid": "GPU-b13f472d-a4a7-4914-a59e-9b73c4856259"},"0000:08:00.0": {"id": "08:00.0","model": "Quadro K4000","vendor": "nvidia","guid": "GPU-ef6c0299-f1bc-7b5c-5291-7cd1a012f8bd"},"0000:0c:00.0": {"id": "0c:00.0","model": "Radeon RX 6400\/6500 XT\/6500M","vendor": "amd","guid": "GPU-639cd727-f368-4fe0-aff3-947542489448"}}', true)); - $data = array() ; - foreach ($array as $gpu) { - $gpustat_cfg["VENDOR"] = $gpu['vendor'] ; - $gpustat_cfg["GPUID"] = $gpu['guid'] ; - $gpustat_cfg["PCIID"] = $gpu['id'] ; - - switch ($gpu['vendor']) { - case 'amd': - $return=(new AMD($gpustat_cfg))->getStatistics(); - $decode = json_decode($return,true); - $decode["panel"] = $gpu['panel'] ; - $data[$gpu["id"]] = $decode; - break; - case 'intel': - $return=(new Intel($gpustat_cfg))->getStatistics(); - $decode = json_decode($return,true); - $decode["panel"] = $gpu['panel'] ; - $data[$gpu["id"]] = $decode; - break; - case 'nvidia': - $return = (new Nvidia($gpustat_cfg))->getStatistics() ; - $decode = json_decode($return,true); - $decode["panel"] = $gpu['panel'] ; - $data[$gpu["id"]] = $decode; - break; - default: - print_r(Error::get(Error::CONFIG_SETTINGS_NOT_VALID)); - } -} -$json=json_encode($data) ; -#Test data -#$json='{"00:02.0":{"clock":100,"fan":50,"memclock":500,"memutil":55,"memused":55,"power":"100W","powermax":500,"rxutil":50,"txutil":60,"temp":50,"tempmax":200,"util":"40%","vendor":"Intel","name":"AlderLake-S GT1","3drender":"50%","blitter":"50%","interrupts":100,"powerutil":"10%","video":"20%","videnh":"30%","panel":1},"03:00.0":{"clock":0,"fan":"N\/A","memclock":"N\/A","memutil":"N\/A","memused":"N\/A","power":"N\/A","powermax":"N\/A","rxutil":"N\/A","txutil":"N\/A","temp":"N\/A","tempmax":"N\/A","util":"0%","vendor":"Intel","name":"DG2 [Arc A770]","3drender":"0%","blitter":"0%","interrupts":0,"powerutil":"0%","video":"0%","videnh":"0%","panel":2},"08:00.0":{"clock":"810","fan":"30%","memclock":"2808","memutil":"50%","memused":"50","power":"28W","powermax":"87","rxutil":50,"txutil":60,"temp":"41 \u00b0C","tempmax":"101 \u00b0C","util":"77%","vendor":"NVIDIA","name":"Quadro K4000","clockmax":"810","memclockmax":"2808","memtotal":"3018","encutil":"50%","decutil":"50%","pciemax":500,"perfstate":"P0","throttled":"No","thrtlrsn":"","pciegen":2,"pciegenmax":2,"pciewidth":1,"pciewidthmax":16,"sessions":0,"uuid":"GPU-ef6c0299-f1bc-7b5c-5291-7cd1a012f8bd","plexusing":true,"plexmem":0,"plexcount":0,"jellyfinusing":true,"jellyfinmem":100,"jellyfincount":2,"handbrakeusing":false,"handbrakemem":0,"handbrakecount":0,"embyusing":false,"embymem":0,"embycount":0,"tdarrusing":false,"tdarrmem":0,"tdarrcount":0,"unmanicusing":true,"unmanicmem":0,"unmaniccount":0,"dizquetvusing":false,"dizquetvmem":0,"dizquetvcount":0,"ersatztvusing":false,"ersatztvmem":0,"ersatztvcount":0,"fileflowsusing":false,"fileflowsmem":0,"fileflowscount":0,"frigateusing":false,"frigatemem":0,"frigatecount":0,"deepstackusing":false,"deepstackmem":0,"deepstackcount":0,"nsfminerusing":false,"nsfminermem":0,"nsfminercount":0,"shinobiprousing":false,"shinobipromem":0,"shinobiprocount":0,"foldinghomeusing":false,"foldinghomemem":0,"foldinghomecount":0,"appssupp":["plex","jellyfin","handbrake","emby","tdarr","unmanic","dizquetv","ersatztv","fileflows","frigate","deepstack","nsfminer","shinobipro","foldinghome"],"panel":3},"0c:00.0":{"clock":2110.5,"fan":200,"memclock":2220.1,"memutil":"21.2%","memused":47.51,"power":50,"powermax":200,"rxutil":"N\/A","txutil":67,"temp":"38 \u00b0C","tempmax":105,"util":"90%","vendor":"AMD","name":"Radeon RX 6400\/6500 XT\/6500M","event":"80%","vertex":"70%","texture":"60%","shaderexp":"50%","sequencer":"40%","shaderinter":"30%","scancon":"30%","primassem":"30%","depthblk":"30%","colorblk":"30%","gfxtrans":"44.1%","transused":11.57,"memclockutil":"9.6%","clockutil":"21.6%","tempunit":"C","fanmax":5550,"voltage":77.7,"voltageunit":"V","panel":4}}' ; -header('Content-Type: application/json'); -header('Content-Length:' . ES . strlen($json)); -echo $json; -file_put_contents("/tmp/gpujson","Time = ".date(DATE_RFC2822)."\n") ; -file_put_contents("/tmp/gpujson",$json."\n",FILE_APPEND) ; + file_put_contents("/tmp/gpuinv",json_encode($gpustat_data)); } diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/lib/Nvidia.php b/src/gpustat/usr/local/emhttp/plugins/gpustat/lib/Nvidia.php index b78900b..3580fc5 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/lib/Nvidia.php +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/lib/Nvidia.php @@ -88,7 +88,7 @@ private function detectApplication (SimpleXMLElement $process) foreach ($commands as $command) { if (strpos($process->process_name, $command) !== false) { // For Handbrake/ffmpeg: arguments tell us which application called it - if (in_array($command, ['ffmpeg', 'HandbrakeCLI', 'python3.8','python3'])) { + if (in_array($command, ['ffmpeg', 'HandbrakeCLI', 'python3.8', 'python3'])) { if (isset($process->pid)) { $pid_info = $this->getFullCommand((int) $process->pid); if (!empty($pid_info) && strlen($pid_info) > 0) { @@ -113,9 +113,19 @@ private function detectApplication (SimpleXMLElement $process) } } } - $this->pageData[$app . 'using'] = true; - $this->pageData[$app . 'mem'] += (int)$this->stripText(' MiB', $process->used_memory); - $this->pageData[$app . 'count']++; + + $usedMemory = (int) $this->stripText(' MiB', $process->used_memory); + $index = array_search($app, array_column($this->pageData['active_apps'], 'name')); + if ($index === false) { + $this->pageData['active_apps'][] = [ + 'name' => $app, + 'mem' => $usedMemory, + 'count' => 1, + ]; + } else { + $this->pageData['active_apps'][$index]['mem'] += $usedMemory; + $this->pageData['active_apps'][$index]['count']++; + } // If we match a more specific command/app to a process, continue on to the next process break 2; } @@ -197,11 +207,11 @@ public function getInventorym(): array } foreach($result as $gpu) { $cmd =self::CMD_UTILITY . ES . sprintf(self::INVENTORY_PARM_PCI, $gpu['guid']) ; - $cmdres = $this->stdout = shell_exec($cmd); + $cmdres = $this->stdout = shell_exec($cmd); $pci = substr($cmdres,14,12); $gpu['id'] = substr($pci,5) ; $gpu['vendor'] = 'nvidia' ; - $result2[$pci] = $gpu ; + $result2[$pci] = $gpu ; } if (empty($result)) $result2=$this->getPCIInventory() ; } @@ -263,7 +273,7 @@ private function getProductName (string $name) if (strlen($name) > 20 && str_word_count($name) > 2) { $words = explode(" ", $name); if ($words[0] == "GeForce") { - array_shift($words) ; + array_shift($words) ; $words2 = implode(" ", $words) ; if (strlen($words2) <= 20) $this->pageData['name'] = $words2; } else $this->pageData['name'] = sprintf("%0s %1s", $words[0], $words[1]); @@ -360,7 +370,7 @@ public function getStatistics() if (!empty($this->stdout) && strlen($this->stdout) > 0) { $this->parseStatistics(); } else { - + $this->pageData['error'][] = Error::get(Error::VENDOR_DATA_NOT_RETURNED); } } else { @@ -377,7 +387,7 @@ public function getStatistics() $this->pageData["vfio"] = false ; $this->pageData["vfiochk"] = $this->checkVFIO("0000:".$this->settings['PCIID']) ; $this->pageData["vfiochkid"] = "0000:".$this->settings['PCIID'] ; - + } else { $this->pageData["vfio"] = true ; $this->pageData["vendor"] = "Nvidia" ; @@ -454,12 +464,7 @@ private function parseStatistics() 'uuid' => 'N/A', ]; - // Set App HW Usage Defaults - foreach (self::SUPPORTED_APPS AS $app => $process) { - $this->pageData[$app . "using"] = false; - $this->pageData[$app . "mem"] = 0; - $this->pageData[$app . "count"] = 0; - } + $this->pageData['active_apps'] = []; if (isset($data->product_name)) { $this->getProductName($data->product_name); } @@ -484,7 +489,6 @@ private function parseStatistics() } // For some reason, encoder_sessions->session_count is not reliable on my install, better to count processes if ($this->settings['DISPSESSIONS']) { - $this->pageData['appssupp'] = array_keys(self::SUPPORTED_APPS); if (isset($data->processes->process_info)) { $this->pageData['sessions'] = count($data->processes->process_info); if ($this->pageData['sessions'] > 0) { diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat b/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat new file mode 100644 index 0000000..f23545c --- /dev/null +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat @@ -0,0 +1,92 @@ +#!/usr/bin/php -q + +getStatistics(); + $decode = json_decode($return, true); + $data[$gpu["id"]] = $decode; + break; + case 'intel': + $return = (new Intel($gpustat_cfg))->getStatistics(); + $decode = json_decode($return, true); + $data[$gpu["id"]] = $decode; + break; + case 'nvidia': + $return = (new Nvidia($gpustat_cfg))->getStatistics() ; + $decode = json_decode($return, true); + $data[$gpu["id"]] = $decode; + break; + default: + print_r(Error::get(Error::CONFIG_SETTINGS_NOT_VALID)); + } + } + + // Test data + // $data = array_merge($data, json_decode('{"00:02.0": {"clock": 100, "fan": 50, "memclock": 500, "memutil": 55, "memused": 55, "power": "100W", "powermax": 500, "rxutil": 50, "txutil": 60, "temp": 50, "tempmax": 200, "util": "40%", "vendor": "Intel", "name": "AlderLake-S GT1", "3drender": "50%", "blitter": "50%", "interrupts": 100, "powerutil": "10%", "video": "20%", "videnh": "30%"}, "09:00.0": {"clock": 0, "fan": "N\/A", "memclock": "N\/A", "memutil": "N\/A", "memused": "N\/A", "power": "N\/A", "powermax": "N\/A", "rxutil": "N\/A", "txutil": "N\/A", "temp": "N\/A", "tempmax": "N\/A", "util": "0%", "vendor": "Intel", "name": "DG2 [Arc A770]", "3drender": "0%", "blitter": "0%", "interrupts": 0, "powerutil": "0%", "video": "0%", "videnh": "0%"}, "08:00.0": {"active_apps":[{"name": "plex", "mem": 214, "count": 2}], "clock": "810", "fan": "30%", "memclock": "2808", "memutil": "50%", "memused": "50", "power": "28W", "powermax": "87", "rxutil": 50, "txutil": 60, "temp": "41 \u00b0C", "tempmax": "101 \u00b0C", "util": "77%", "vendor": "NVIDIA", "name": "Quadro K4000", "clockmax": "810", "memclockmax": "2808", "memtotal": "3018", "encutil": "50%", "decutil": "50%", "pciemax": 500, "perfstate": "P0", "throttled": "No", "thrtlrsn": "", "pciegen": 2, "pciegenmax": 2, "pciewidth": 1, "pciewidthmax": 16, "sessions": 2, "uuid": "GPU-ef6c0299-f1bc-7b5c-5291-7cd1a012f8bd"}, "0c:00.0": {"clock": 2110.5, "fan": 200, "memclock": 2220.1, "memutil": "21.2%", "memused": 47.51, "power": 50, "powermax": 200, "rxutil": "N\/A", "txutil": 67, "temp": "38 \u00b0C", "tempmax": 105, "util": "90%", "vendor": "AMD", "name": "Radeon RX 6400\/6500 XT\/6500M", "event": "80%", "vertex": "70%", "texture": "60%", "shaderexp": "50%", "sequencer": "40%", "shaderinter": "30%", "scancon": "30%", "primassem": "30%", "depthblk": "30%", "colorblk": "30%", "gfxtrans": "44.1%", "transused": 11.57, "memclockutil": "9.6%", "clockutil": "21.6%", "tempunit": "C", "fanmax": 5550, "voltage": 77.7, "voltageunit": "V"}}', true)); + + $json = json_encode($data) ; + + publish('gpustat', $json); + + file_put_contents("/tmp/gpujson", "Time = " . date(DATE_RFC2822) . "\n" . $json . "\n") ; + + if ($gpustat_cfg['UIREFRESH'] != '1') { + exit; + } + + sleep(round($gpustat_cfg['UIREFRESHINT'] / 1000)); +} diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js index e321b54..48e0343 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js @@ -23,60 +23,71 @@ */ -function toggleVFIO(vfio,panel) { +function toggleVFIO(vfio, panel) { if (vfio) { - $('.vfio_inuse'+panel).show(); - $('.vfio_notinuse'+panel).hide(); - $('.vfio_status'+panel).text(_("GPU not available bound to VFIO or inuse in a VM.")); + $('.vfio_inuse', panel).show(); + $('.vfio_notinuse', panel).hide(); + $('.vfio_status', panel).text(_("GPU not available bound to VFIO or inuse in a VM.")); } else { - $('.vfio_inuse'+panel).hide(); - $('.vfio_notinuse'+panel).show(); + $('.vfio_inuse', panel).hide(); + $('.vfio_notinuse', panel).show(); } - } +} -const gpustat_statusm = (input) => { - $.getJSON('/plugins/gpustat/gpustatusmulti.php?gpus='+JSON.stringify(input), (data2) => { - if (data2) { +const parseStats = (data2) => { + if (data2) { $.each(data2, function (key2, data) { - panel = data["panel"] ; + panel = 'tbody[data-gpu-id="' + key2 + '"]'; if (!data['vfio']) { - toggleVFIO(false,panel) ; + toggleVFIO(false, panel); switch (data["vendor"]) { case 'NVIDIA': // Nvidia Slider Bars - $('.gpu-memclockbar'+panel).removeAttr('style').css('width', data["memclock"] / data["memclockmax"] * 100 + "%"); - $('.gpu-gpuclockbar'+panel ).removeAttr('style').css('width', data["clock"] / data["clockmax"] * 100 + "%"); - $('.gpu-powerbar'+panel ).removeAttr('style').css('width', parseInt(data["power"].replace("W","") / data["powermax"] * 100) + "%"); - $('.gpu-rxutilbar'+panel).removeAttr('style').css('width', parseInt(data["rxutil"] / data["pciemax"] * 100) + "%"); - $('.gpu-txutilbar'+panel).removeAttr('style').css('width', parseInt(data["txutil"] / data["pciemax"] * 100) + "%"); + $('.gpu-memclockbar', panel).removeAttr('style').css('width', data["memclock"] / data["memclockmax"] * 100 + "%"); + $('.gpu-gpuclockbar', panel).removeAttr('style').css('width', data["clock"] / data["clockmax"] * 100 + "%"); + $('.gpu-powerbar', panel).removeAttr('style').css('width', parseInt(data["power"].replace("W", "") / data["powermax"] * 100) + "%"); + $('.gpu-rxutilbar', panel).removeAttr('style').css('width', parseInt(data["rxutil"] / data["pciemax"] * 100) + "%"); + $('.gpu-txutilbar', panel).removeAttr('style').css('width', parseInt(data["txutil"] / data["pciemax"] * 100) + "%"); let nvidiabars = ['util', 'memutil', 'encutil', 'decutil', 'fan']; nvidiabars.forEach(function (metric) { - $('.gpu-'+metric+'bar'+panel).removeAttr('style').css('width', data[metric]); + $('.gpu-' + metric + 'bar', panel).removeAttr('style').css('width', data[metric]); }); - if (data["appssupp"]) { - data["appssupp"].forEach(function (app) { - if (data[app + "using"]) { - $('.gpu-img-span-'+app+panel).css('display', "inline"); - $('#gpu-'+app+panel).attr('title', "Count: " + data[app+"count"] + " Memory: " + data[app+"mem"] + "MB"); + if (data["active_apps"]) { + const appList = []; + $('.gpu-active-apps .gpu-img-span', panel).each(function () { + appList.push($(this).data('name')); + }); + const active_apps = []; + data["active_apps"].forEach(function (app) { + active_apps.push(app.name); + const title = 'Count: ' + app.count + ' - Memory: ' + app.mem + 'MB'; + if (appList.includes(app.name)) { + $('.gpu-active-apps td span[data-name="' + app.name + '"] img', panel).attr('title', title); } else { - $('.gpu-img-span-'+app+panel).css('display', "none"); - $('#gpu-'+app+panel).attr('title', ""); + const img = $(''); + const span = $(''); + span.append(img); + $('.gpu-active-apps td', panel).append(span); } }); + $('.gpu-active-apps td span.gpu-img-span', panel).each(function () { + if (!active_apps.includes($(this).data('name'))) + $(this).remove(); + }); } break; case 'Intel': // Intel Slider Bars let intelbars = ['3drender', 'blitter', 'video', 'videnh', 'powerutil']; intelbars.forEach(function (metric) { - $('.gpu-'+metric+'bar'+panel).removeAttr('style').css('width', data[metric]); + $('.gpu-' + metric + 'bar', panel).removeAttr('style').css('width', data[metric]); }); break; case 'AMD': - $('.gpu-powerbar'+panel).removeAttr('style').css('width', parseInt(data["power"] / data["powermax"] * 100) + "%"); - $('.gpu-fanbar'+panel).removeAttr('style').css('width', parseInt(data["fan"] / data["fanmax"] * 100) + "%"); + $('.gpu-powerbar', panel).removeAttr('style').css('width', parseInt(data["power"] / data["powermax"] * 100) + "%"); + $('.gpu-fanbar', panel).removeAttr('style').css('width', parseInt(data["fan"] / data["fanmax"] * 100) + "%"); let amdbars = [ 'util', 'event', 'vertex', 'texture', 'shaderexp', 'sequencer', @@ -85,39 +96,36 @@ const gpustat_statusm = (input) => { 'gfxtrans', 'memclockutil', 'clockutil' ]; amdbars.forEach(function (metric) { - $('.gpu-'+metric+'bar'+panel).removeAttr('style').css('width', data[metric]); + $('.gpu-' + metric + 'bar', panel).removeAttr('style').css('width', data[metric]); }); break; } $.each(data, function (key, data) { if (key == "error") { - toggleVFIO(true,panel) ; - var error_text = data[0]["message"] ; - $('.vfio_status'+panel).text(_(error_text)); + toggleVFIO(true, panel); + var error_text = data[0]["message"]; + $('.vfio_status', panel).text(_(error_text)); } - $('.gpu-'+key+panel).html(data); - }) + $('.gpu-' + key, panel).html(data); + }) } else { - toggleVFIO(true,panel) ; - $('.gpu-name'+panel).html(data["name"]); - $('.gpu-vendor'+panel).html(data["vendor"]); + toggleVFIO(true, panel); + $('.gpu-name', panel).html(data["name"]); + $('.gpu-vendor', panel).html(data["vendor"]); } var hidden = $.cookie('hidden_content'); if (hidden) { hidden = hidden.split(';'); - if (hidden.includes($("#tblGPUDash" + panel).attr('title').md5())) - $("#tblGPUDash" + panel ).mixedView(0); + if (hidden.includes($("#tblGPUDash", panel).attr('title').md5())) + $("#tblGPUDash", panel).mixedView(0); } - - }) - } - - }); -}; + }) + } +} /* From c53a46969da24c1ca9f63357f0e0cfd2b7e0d405 Mon Sep 17 00:00:00 2001 From: Peuuuur-Noel Date: Sun, 5 May 2024 12:42:53 +0000 Subject: [PATCH 2/8] Make script executable --- src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat b/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat old mode 100644 new mode 100755 From 563471bfc716cb3116ea738366af5d37aa46bb37 Mon Sep 17 00:00:00 2001 From: Peuuuur-Noel Date: Mon, 6 May 2024 18:48:16 +0000 Subject: [PATCH 3/8] - Change the way nchan process is restart - Update refresh for non multi (Unraid pre 6.12) --- .../plugins/gpustat/GPUStatSettings.page | 9 +- .../emhttp/plugins/gpustat/css/style.css | 8 +- .../emhttp/plugins/gpustat/gpustatus.page | 29 ++-- .../emhttp/plugins/gpustat/gpustatus.php | 24 ---- .../gpustat/gpustatusmovablemulti.page | 2 +- .../emhttp/plugins/gpustat/nchan/gpustat | 57 +++++--- .../emhttp/plugins/gpustat/scripts/gpustat.js | 126 ++++++++++-------- 7 files changed, 132 insertions(+), 123 deletions(-) diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page b/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page index dc621f9..e610e20 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page @@ -98,14 +98,7 @@ Title="GPU Statistics" $cfg = NULL ; if ($_POST['#apply'] == "_(Apply)_") { array_map(function($k, $v) use (&$cfg) { if($k[0] != "#") $cfg[$k] = $v; }, array_keys($_POST), $_POST ); - save_cfg($cfg,$gpustat_data) ; - - // Restart nchan gpustat if not running when refresh setting set to Yes - $pid = exec('pgrep gpustat'); - if (!$pid && $_POST['UIREFRESH'] == '1' && $gpustat_cfg['UIREFRESH'] != '1') { - exec('/usr/local/emhttp/plugins/gpustat/nchan/gpustat &>/dev/null &'); - } - + save_cfg($cfg,$gpustat_data); $gpustat_cfg = parse_plugin_cfg("gpustat", true); unset($_POST); } diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css b/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css index 66981c4..b1d67ed 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css @@ -26,13 +26,17 @@ margin-top: 0; } -span.gpu { +.gpustat span.gpu { width: 150px; display: inline-block; } -.gpu-image { +.gpustat .gpu-image { padding-left: 8px; height: 32px; width: 32px; +} + +.gpustat .usage-disk > span { + transition: width 0.5s; } \ No newline at end of file diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.page b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.page index f4fe4ef..67a68b2 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.page +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.page @@ -1,6 +1,7 @@ Menu="Dashboard" Icon="gpustat.png" Cond="version_compare(parse_ini_file('/etc/unraid-version')['version'],'6.12.0-beta6', '<')" +Nchan="gpustat" --- - + @@ -164,13 +160,7 @@ Cond="version_compare(parse_ini_file('/etc/unraid-version')['version'],'6.12.0-b Active Apps - - - - - - - + @@ -353,10 +343,13 @@ Cond="version_compare(parse_ini_file('/etc/unraid-version')['version'],'6.12.0-b + diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php index 6b0f28a..44d85f1 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php @@ -30,13 +30,11 @@ include 'lib/Nvidia.php'; include 'lib/Intel.php'; include 'lib/AMD.php'; -include 'lib/Error.php'; use gpustat\lib\AMD; use gpustat\lib\Main; use gpustat\lib\Nvidia; use gpustat\lib\Intel; -use gpustat\lib\Error; if (!isset($gpustat_cfg)) { $gpustat_cfg = Main::getSettings(); @@ -47,26 +45,4 @@ $gpustat_cfg['inventory'] = true; // Settings page looks for $gpustat_data specifically -- inventory all supported GPU types $gpustat_data = array_merge((new Nvidia($gpustat_cfg))->getInventory(), (new Intel($gpustat_cfg))->getInventory(), (new AMD($gpustat_cfg))->getInventory()); -} else { - - switch ($gpustat_cfg['VENDOR']) { - case 'amd': - $data = (new AMD($gpustat_cfg))->getStatistics(); - break; - case 'intel': - $data = (new Intel($gpustat_cfg))->getStatistics(); - break; - case 'nvidia': - $data = (new Nvidia($gpustat_cfg))->getStatistics(); - break; - default: - print_r(Error::get(Error::CONFIG_SETTINGS_NOT_VALID)); - } - $json = $data ; - header('Content-Type: application/json'); - header('Content-Length:' . ES . strlen($json)); - echo $json; - file_put_contents("/tmp/gpujson2","Time = ".date(DATE_RFC2822)."\n") ; - file_put_contents("/tmp/gpujson2",$json."\n",FILE_APPEND) ; - } diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page index 0a906f7..7880451 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page @@ -90,7 +90,7 @@ foreach ($multigpus as $id=>$gpu) { $layout = GPULayout($gpu["vendor"],$gpustat_cfg) ; $mytiles[$pluginname.$k]['column'.$j] = << + $stats diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat b/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat index f23545c..d752cd6 100755 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/nchan/gpustat @@ -43,48 +43,69 @@ use gpustat\lib\Nvidia; use gpustat\lib\Intel; use gpustat\lib\Error; +$gpustat_multi_enable = version_compare(parse_ini_file('/etc/unraid-version')['version'], '6.12.0-beta5', '>'); + while (true) { $gpustat_cfg = Main::getSettings(); - $multi = urldecode($gpustat_cfg["MULTIGPUJSON"]); - $multigpus = json_decode($multi, true); - $data = array() ; + $data = array(); + + if ($gpustat_multi_enable) { + $multi = urldecode($gpustat_cfg["MULTIGPUJSON"]); + $multigpus = json_decode($multi, true); + } else { + $multigpus = [ + [ + 'vendor' => $gpustat_cfg["VENDOR"], + 'guid' => $gpustat_cfg["GPUID"], + 'id' => null, + ], + ]; + } foreach ($multigpus as $gpu) { - $gpustat_cfg["VENDOR"] = $gpu['vendor'] ; - $gpustat_cfg["GPUID"] = $gpu['guid'] ; - $gpustat_cfg["PCIID"] = $gpu['id'] ; + if ($gpustat_multi_enable) { + $gpustat_cfg["VENDOR"] = $gpu['vendor']; + $gpustat_cfg["GPUID"] = $gpu['guid']; + $gpustat_cfg["PCIID"] = $gpu['id']; + } switch ($gpu['vendor']) { case 'amd': $return = (new AMD($gpustat_cfg))->getStatistics(); - $decode = json_decode($return, true); - $data[$gpu["id"]] = $decode; break; case 'intel': $return = (new Intel($gpustat_cfg))->getStatistics(); - $decode = json_decode($return, true); - $data[$gpu["id"]] = $decode; break; case 'nvidia': - $return = (new Nvidia($gpustat_cfg))->getStatistics() ; - $decode = json_decode($return, true); - $data[$gpu["id"]] = $decode; + $return = (new Nvidia($gpustat_cfg))->getStatistics(); break; default: print_r(Error::get(Error::CONFIG_SETTINGS_NOT_VALID)); } - } - // Test data - // $data = array_merge($data, json_decode('{"00:02.0": {"clock": 100, "fan": 50, "memclock": 500, "memutil": 55, "memused": 55, "power": "100W", "powermax": 500, "rxutil": 50, "txutil": 60, "temp": 50, "tempmax": 200, "util": "40%", "vendor": "Intel", "name": "AlderLake-S GT1", "3drender": "50%", "blitter": "50%", "interrupts": 100, "powerutil": "10%", "video": "20%", "videnh": "30%"}, "09:00.0": {"clock": 0, "fan": "N\/A", "memclock": "N\/A", "memutil": "N\/A", "memused": "N\/A", "power": "N\/A", "powermax": "N\/A", "rxutil": "N\/A", "txutil": "N\/A", "temp": "N\/A", "tempmax": "N\/A", "util": "0%", "vendor": "Intel", "name": "DG2 [Arc A770]", "3drender": "0%", "blitter": "0%", "interrupts": 0, "powerutil": "0%", "video": "0%", "videnh": "0%"}, "08:00.0": {"active_apps":[{"name": "plex", "mem": 214, "count": 2}], "clock": "810", "fan": "30%", "memclock": "2808", "memutil": "50%", "memused": "50", "power": "28W", "powermax": "87", "rxutil": 50, "txutil": 60, "temp": "41 \u00b0C", "tempmax": "101 \u00b0C", "util": "77%", "vendor": "NVIDIA", "name": "Quadro K4000", "clockmax": "810", "memclockmax": "2808", "memtotal": "3018", "encutil": "50%", "decutil": "50%", "pciemax": 500, "perfstate": "P0", "throttled": "No", "thrtlrsn": "", "pciegen": 2, "pciegenmax": 2, "pciewidth": 1, "pciewidthmax": 16, "sessions": 2, "uuid": "GPU-ef6c0299-f1bc-7b5c-5291-7cd1a012f8bd"}, "0c:00.0": {"clock": 2110.5, "fan": 200, "memclock": 2220.1, "memutil": "21.2%", "memused": 47.51, "power": 50, "powermax": 200, "rxutil": "N\/A", "txutil": 67, "temp": "38 \u00b0C", "tempmax": 105, "util": "90%", "vendor": "AMD", "name": "Radeon RX 6400\/6500 XT\/6500M", "event": "80%", "vertex": "70%", "texture": "60%", "shaderexp": "50%", "sequencer": "40%", "shaderinter": "30%", "scancon": "30%", "primassem": "30%", "depthblk": "30%", "colorblk": "30%", "gfxtrans": "44.1%", "transused": 11.57, "memclockutil": "9.6%", "clockutil": "21.6%", "tempunit": "C", "fanmax": 5550, "voltage": 77.7, "voltageunit": "V"}}', true)); + if ($gpustat_multi_enable) { + $decode = json_decode($return, true); + + if ($decode != NULL) { + $data[$gpu["id"]] = $decode; + } + + // Test data + // $data = array_merge($data, json_decode('{"00:02.0": {"clock": 100, "fan": 50, "memclock": 500, "memutil": 55, "memused": 55, "power": "100W", "powermax": 500, "rxutil": 50, "txutil": 60, "temp": 50, "tempmax": 200, "util": "40%", "vendor": "Intel", "name": "AlderLake-S GT1", "3drender": "50%", "blitter": "50%", "interrupts": 100, "powerutil": "10%", "video": "20%", "videnh": "30%"}, "09:00.0": {"clock": 0, "fan": "N\/A", "memclock": "N\/A", "memutil": "N\/A", "memused": "N\/A", "power": "N\/A", "powermax": "N\/A", "rxutil": "N\/A", "txutil": "N\/A", "temp": "N\/A", "tempmax": "N\/A", "util": "0%", "vendor": "Intel", "name": "DG2 [Arc A770]", "3drender": "0%", "blitter": "0%", "interrupts": 0, "powerutil": "0%", "video": "0%", "videnh": "0%"}, "08:00.0": {"active_apps":[{"name": "plex", "mem": 214, "count": 2}], "clock": "810", "fan": "30%", "memclock": "2808", "memutil": "50%", "memused": "50", "power": "28W", "powermax": "87", "rxutil": 50, "txutil": 60, "temp": "41 \u00b0C", "tempmax": "101 \u00b0C", "util": "77%", "vendor": "NVIDIA", "name": "Quadro K4000", "clockmax": "810", "memclockmax": "2808", "memtotal": "3018", "encutil": "50%", "decutil": "50%", "pciemax": 500, "perfstate": "P0", "throttled": "No", "thrtlrsn": "", "pciegen": 2, "pciegenmax": 2, "pciewidth": 1, "pciewidthmax": 16, "sessions": 2, "uuid": "GPU-ef6c0299-f1bc-7b5c-5291-7cd1a012f8bd"}, "0c:00.0": {"clock": 2110.5, "fan": 200, "memclock": 2220.1, "memutil": "21.2%", "memused": 47.51, "power": 50, "powermax": 200, "rxutil": "N\/A", "txutil": 67, "temp": "38 \u00b0C", "tempmax": 105, "util": "90%", "vendor": "AMD", "name": "Radeon RX 6400\/6500 XT\/6500M", "event": "80%", "vertex": "70%", "texture": "60%", "shaderexp": "50%", "sequencer": "40%", "shaderinter": "30%", "scancon": "30%", "primassem": "30%", "depthblk": "30%", "colorblk": "30%", "gfxtrans": "44.1%", "transused": 11.57, "memclockutil": "9.6%", "clockutil": "21.6%", "tempunit": "C", "fanmax": 5550, "voltage": 77.7, "voltageunit": "V"}}', true)); - $json = json_encode($data) ; + $json = json_encode($data); + } else { + $json = $return; + } + } publish('gpustat', $json); - file_put_contents("/tmp/gpujson", "Time = " . date(DATE_RFC2822) . "\n" . $json . "\n") ; + file_put_contents("/tmp/gpujson", "Time = " . date(DATE_RFC2822) . PHP_EOL . $json . PHP_EOL); + // Stop nchan gpustat if refresh setting set to No and remove it from /var/run/nchan.pid if ($gpustat_cfg['UIREFRESH'] != '1') { + exec('sed -i "/plugins\/gpustat\/nchan\/gpustat/d" /var/run/nchan.pid'); exit; } diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js index 828f12f..1a900cd 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js @@ -22,63 +22,85 @@ SOFTWARE. */ -const gpustat_status = () => { - $.getJSON('/plugins/gpustat/gpustatus.php', (data) => { - if (data) { - switch (data["vendor"]) { - case 'NVIDIA': - // Nvidia Slider Bars - $('.gpu-memclockbar').removeAttr('style').css('width', data["memclock"] / data["memclockmax"] * 100 + "%"); - $('.gpu-gpuclockbar').removeAttr('style').css('width', data["clock"] / data["clockmax"] * 100 + "%"); - $('.gpu-powerbar').removeAttr('style').css('width', parseInt(data["power"].replace("W","") / data["powermax"] * 100) + "%"); - $('.gpu-rxutilbar').removeAttr('style').css('width', parseInt(data["rxutil"] / data["pciemax"] * 100) + "%"); - $('.gpu-txutilbar').removeAttr('style').css('width', parseInt(data["txutil"] / data["pciemax"] * 100) + "%"); +const parseStats = (data) => { + if (data) { + switch (data["vendor"]) { + case 'NVIDIA': + // Nvidia Slider Bars + $('.gpu-memclockbar').removeAttr('style').css('width', data["memclock"] / data["memclockmax"] * 100 + "%"); + $('.gpu-gpuclockbar').removeAttr('style').css('width', data["clock"] / data["clockmax"] * 100 + "%"); + $('.gpu-powerbar').removeAttr('style').css('width', parseInt(data["power"].replace("W","") / data["powermax"] * 100) + "%"); + $('.gpu-rxutilbar').removeAttr('style').css('width', parseInt(data["rxutil"] / data["pciemax"] * 100) + "%"); + $('.gpu-txutilbar').removeAttr('style').css('width', parseInt(data["txutil"] / data["pciemax"] * 100) + "%"); - let nvidiabars = ['util', 'memutil', 'encutil', 'decutil', 'fan']; - nvidiabars.forEach(function (metric) { - $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]); - }); + let nvidiabars = ['util', 'memutil', 'encutil', 'decutil', 'fan']; + nvidiabars.forEach(function (metric) { + $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]); + }); - if (data["appssupp"]) { - data["appssupp"].forEach(function (app) { - if (data[app + "using"]) { - $('.gpu-img-span-'+app).css('display', "inline"); - $('#gpu-'+app).attr('title', "Count: " + data[app+"count"] + " Memory: " + data[app+"mem"] + "MB"); - } else { - $('.gpu-img-span-'+app).css('display', "none"); - $('#gpu-'+app).attr('title', ""); - } - }); - } - break; - case 'Intel': - // Intel Slider Bars - let intelbars = ['3drender', 'blitter', 'video', 'videnh', 'powerutil']; - intelbars.forEach(function (metric) { - $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]); - }); - break; - case 'AMD': - $('.gpu-powerbar').removeAttr('style').css('width', parseInt(data["power"] / data["powermax"] * 100) + "%"); - $('.gpu-fanbar').removeAttr('style').css('width', parseInt(data["fan"] / data["fanmax"] * 100) + "%"); - let amdbars = [ - 'util', 'event', 'vertex', - 'texture', 'shaderexp', 'sequencer', - 'shaderinter', 'scancon', 'primassem', - 'depthblk', 'colorblk', 'memutil', - 'gfxtrans', 'memclockutil', 'clockutil' - ]; - amdbars.forEach(function (metric) { - $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]); + if (data["appssupp"]) { + data["appssupp"].forEach(function (app) { + if (data[app + "using"]) { + $('.gpu-img-span-'+app).css('display', "inline"); + $('#gpu-'+app).attr('title', "Count: " + data[app+"count"] + " Memory: " + data[app+"mem"] + "MB"); + } else { + $('.gpu-img-span-'+app).css('display', "none"); + $('#gpu-'+app).attr('title', ""); + } }); - break; - } + } + break; + case 'Intel': + // Intel Slider Bars + let intelbars = ['3drender', 'blitter', 'video', 'videnh', 'powerutil']; + intelbars.forEach(function (metric) { + $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]); + }); + break; + case 'AMD': + $('.gpu-powerbar').removeAttr('style').css('width', parseInt(data["power"] / data["powermax"] * 100) + "%"); + $('.gpu-fanbar').removeAttr('style').css('width', parseInt(data["fan"] / data["fanmax"] * 100) + "%"); + let amdbars = [ + 'util', 'event', 'vertex', + 'texture', 'shaderexp', 'sequencer', + 'shaderinter', 'scancon', 'primassem', + 'depthblk', 'colorblk', 'memutil', + 'gfxtrans', 'memclockutil', 'clockutil' + ]; + amdbars.forEach(function (metric) { + $('.gpu-'+metric+'bar').removeAttr('style').css('width', data[metric]); + }); + break; + } - $.each(data, function (key, data) { - $('.gpu-'+key).html(data); - }) + if (data["active_apps"]) { + const appList = []; + $('.gpu-active-apps .gpu-img-span').each(function () { + appList.push($(this).data('name')); + }); + const active_apps = []; + data["active_apps"].forEach(function (app) { + active_apps.push(app.name); + const title = 'Count: ' + app.count + ' - Memory: ' + app.mem + 'MB'; + if (appList.includes(app.name)) { + $('.gpu-active-apps span[data-name="' + app.name + '"] img').attr('title', title); + } else { + const img = $(''); + const span = $(''); + span.append(img); + $('.gpu-active-apps').append(span); + } + }); + $('.gpu-active-apps td span.gpu-img-span').each(function () { + if (!active_apps.includes($(this).data('name'))) + $(this).remove(); + }); } - }); + + $.each(data, function (key, data) { + $('.gpu-'+key).html(data); + }) + } }; const gpustat_dash = () => { From 18759a2ea222f42fb30f92ab05d470b74cbfa0fb Mon Sep 17 00:00:00 2001 From: Peuuuur-Noel Date: Mon, 6 May 2024 21:25:34 +0000 Subject: [PATCH 4/8] Remove duplicate version compare --- .../usr/local/emhttp/plugins/gpustat/GPUStatSettings.page | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page b/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page index e610e20..659800b 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page @@ -82,7 +82,7 @@ Title="GPU Statistics" $cfg = $gpustat_cfg = parse_plugin_cfg("gpustat", true); $gpustat_inventory = true; - $multi_enable=version_compare(parse_ini_file('/etc/unraid-version')['version'],'6.12.0-beta5', '>') ; + $multi_enable = version_compare(parse_ini_file('/etc/unraid-version')['version'], '6.12.0-beta5', '>'); if ($multi_enable) { include_once './plugins/gpustat/gpustatusmulti.php'; @@ -90,10 +90,6 @@ Title="GPU Statistics" include_once './plugins/gpustat/gpustatus.php'; } - - - $multi_enable=version_compare(parse_ini_file('/etc/unraid-version')['version'],'6.12.0-beta5', '>') ; - if (count($_POST)) { $cfg = NULL ; if ($_POST['#apply'] == "_(Apply)_") { From 8a70c004aba4afef8d2abd11ee40017d3c447a09 Mon Sep 17 00:00:00 2001 From: Peuuuur-Noel Date: Mon, 6 May 2024 21:34:00 +0000 Subject: [PATCH 5/8] Merge files gpustatus.php and gpustatusmulti.php to GPUStatSettings.page --- .../plugins/gpustat/GPUStatSettings.page | 23 ++++++-- .../emhttp/plugins/gpustat/gpustatus.php | 48 ----------------- .../emhttp/plugins/gpustat/gpustatusmulti.php | 54 ------------------- 3 files changed, 19 insertions(+), 106 deletions(-) delete mode 100644 src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php delete mode 100644 src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmulti.php diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page b/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page index 659800b..edbfe85 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/GPUStatSettings.page @@ -80,14 +80,29 @@ Title="GPU Statistics" } $cfg = $gpustat_cfg = parse_plugin_cfg("gpustat", true); - $gpustat_inventory = true; - $multi_enable = version_compare(parse_ini_file('/etc/unraid-version')['version'], '6.12.0-beta5', '>'); + const ES = ' '; + + require_once $docroot . '/plugins/gpustat/lib/Main.php'; + require_once $docroot . '/plugins/gpustat/lib/Nvidia.php'; + require_once $docroot . '/plugins/gpustat/lib/Intel.php'; + require_once $docroot . '/plugins/gpustat/lib/AMD.php'; + require_once $docroot . '/plugins/gpustat/lib/Error.php'; + + use gpustat\lib\AMD; + use gpustat\lib\Nvidia; + use gpustat\lib\Intel; + use gpustat\lib\Error; + + // Settings page looks for $gpustat_data specifically -- inventory all supported GPU types if ($multi_enable) { - include_once './plugins/gpustat/gpustatusmulti.php'; + $gpustat_data = array_merge((new Nvidia($gpustat_cfg))->getInventorym(), (new Intel($gpustat_cfg))->getInventory(), (new AMD($gpustat_cfg))->getInventorym()); + + // Test data for multigpu + // $gpustat_data = array_merge($gpustat_data, json_decode('{"0000:00:02.0": {"id": "00:02.0","model": "AlderLake-S GT1","vendor": "intel","guid": "GPU-94118c02-132c-45bb-a114-df6f24902d5d"},"0000:09:00.0": {"id": "09:00.0","model": "DG2 [Arc A770]","vendor": "intel","guid": "GPU-b13f472d-a4a7-4914-a59e-9b73c4856259"},"0000:08:00.0": {"id": "08:00.0","model": "Quadro K4000","vendor": "nvidia","guid": "GPU-ef6c0299-f1bc-7b5c-5291-7cd1a012f8bd"},"0000:0c:00.0": {"id": "0c:00.0","model": "Radeon RX 6400\/6500 XT\/6500M","vendor": "amd","guid": "GPU-639cd727-f368-4fe0-aff3-947542489448"}}', true)); } else { - include_once './plugins/gpustat/gpustatus.php'; + $gpustat_data = array_merge((new Nvidia($gpustat_cfg))->getInventory(), (new Intel($gpustat_cfg))->getInventory(), (new AMD($gpustat_cfg))->getInventory()); } if (count($_POST)) { diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php deleted file mode 100644 index 44d85f1..0000000 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php +++ /dev/null @@ -1,48 +0,0 @@ -getInventory(), (new Intel($gpustat_cfg))->getInventory(), (new AMD($gpustat_cfg))->getInventory()); -} diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmulti.php b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmulti.php deleted file mode 100644 index e6da40a..0000000 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmulti.php +++ /dev/null @@ -1,54 +0,0 @@ -getInventorym(), (new Intel($gpustat_cfg))->getInventory(), (new AMD($gpustat_cfg))->getInventorym()); - - // Test data - // $gpustat_data = array_merge($gpustat_data, json_decode('{"0000:00:02.0": {"id": "00:02.0","model": "AlderLake-S GT1","vendor": "intel","guid": "GPU-94118c02-132c-45bb-a114-df6f24902d5d"},"0000:09:00.0": {"id": "09:00.0","model": "DG2 [Arc A770]","vendor": "intel","guid": "GPU-b13f472d-a4a7-4914-a59e-9b73c4856259"},"0000:08:00.0": {"id": "08:00.0","model": "Quadro K4000","vendor": "nvidia","guid": "GPU-ef6c0299-f1bc-7b5c-5291-7cd1a012f8bd"},"0000:0c:00.0": {"id": "0c:00.0","model": "Radeon RX 6400\/6500 XT\/6500M","vendor": "amd","guid": "GPU-639cd727-f368-4fe0-aff3-947542489448"}}', true)); - - file_put_contents("/tmp/gpuinv",json_encode($gpustat_data)); -} From 67ee4b6a13fd8f951e19111118fc2bf46f6b52c4 Mon Sep 17 00:00:00 2001 From: Peuuuur-Noel Date: Tue, 7 May 2024 17:55:40 +0000 Subject: [PATCH 6/8] Revert to ajax polling for non multigpu. --- .../emhttp/plugins/gpustat/gpustatus.page | 16 ++--- .../emhttp/plugins/gpustat/gpustatus.php | 60 +++++++++++++++++++ .../emhttp/plugins/gpustat/scripts/gpustat.js | 16 +++-- .../plugins/gpustat/scripts/gpustatmulti.js | 11 ++-- 4 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.page b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.page index 67a68b2..1855ff5 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.page +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.page @@ -1,7 +1,6 @@ Menu="Dashboard" Icon="gpustat.png" Cond="version_compare(parse_ini_file('/etc/unraid-version')['version'],'6.12.0-beta6', '<')" -Nchan="gpustat" --- - diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php new file mode 100644 index 0000000..b989ba6 --- /dev/null +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatus.php @@ -0,0 +1,60 @@ +getStatistics(); + break; + case 'intel': + $json = (new Intel($gpustat_cfg))->getStatistics(); + break; + case 'nvidia': + $json = (new Nvidia($gpustat_cfg))->getStatistics(); + break; + default: + print_r(Error::get(Error::CONFIG_SETTINGS_NOT_VALID)); +} + +header('Content-Type: application/json'); +header('Content-Length:' . ES . strlen($json)); +echo $json; +file_put_contents("/tmp/gpujson2", "Time = " . date(DATE_RFC2822) . PHP_EOL . $json . PHP_EOL); diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js index 1a900cd..a2bce3a 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustat.js @@ -75,10 +75,13 @@ const parseStats = (data) => { if (data["active_apps"]) { const appList = []; + const active_apps = []; $('.gpu-active-apps .gpu-img-span').each(function () { - appList.push($(this).data('name')); + const name = $(this).data('name'); + if (!appList.includes(name)) { + appList.push(name); + } }); - const active_apps = []; data["active_apps"].forEach(function (app) { active_apps.push(app.name); const title = 'Count: ' + app.count + ' - Memory: ' + app.mem + 'MB'; @@ -91,9 +94,10 @@ const parseStats = (data) => { $('.gpu-active-apps').append(span); } }); - $('.gpu-active-apps td span.gpu-img-span').each(function () { - if (!active_apps.includes($(this).data('name'))) + $('.gpu-active-apps .gpu-img-span').each(function () { + if (!active_apps.includes($(this).data('name'))) { $(this).remove(); + } }); } @@ -103,6 +107,10 @@ const parseStats = (data) => { } }; +const gpustat_status = () => { + $.getJSON('/plugins/gpustat/gpustatus.php', (data) => parseStats(data)); +}; + const gpustat_dash = () => { // append data from the table into the correct one $('#db-box1').append($('.dash_gpustat').html()); diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js index 48e0343..c7ef023 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/scripts/gpustatmulti.js @@ -56,15 +56,18 @@ const parseStats = (data2) => { if (data["active_apps"]) { const appList = []; + const active_apps = []; $('.gpu-active-apps .gpu-img-span', panel).each(function () { - appList.push($(this).data('name')); + const name = $(this).data('name'); + if (!appList.includes(name)) { + appList.push(name); + } }); - const active_apps = []; data["active_apps"].forEach(function (app) { active_apps.push(app.name); const title = 'Count: ' + app.count + ' - Memory: ' + app.mem + 'MB'; if (appList.includes(app.name)) { - $('.gpu-active-apps td span[data-name="' + app.name + '"] img', panel).attr('title', title); + $('.gpu-active-apps span[data-name="' + app.name + '"] img', panel).attr('title', title); } else { const img = $(''); const span = $(''); @@ -72,7 +75,7 @@ const parseStats = (data2) => { $('.gpu-active-apps td', panel).append(span); } }); - $('.gpu-active-apps td span.gpu-img-span', panel).each(function () { + $('.gpu-active-apps .gpu-img-span', panel).each(function () { if (!active_apps.includes($(this).data('name'))) $(this).remove(); }); From 1b492f229f2b85ab346e245608f18463a06e31b6 Mon Sep 17 00:00:00 2001 From: Peuuuur-Noel Date: Thu, 9 May 2024 21:17:23 +0000 Subject: [PATCH 7/8] Small style changes --- src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css b/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css index b1d67ed..51209ee 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/css/style.css @@ -31,6 +31,10 @@ display: inline-block; } +.gpustat span[class*="gpu-throttled"] { + margin-right: 5px; +} + .gpustat .gpu-image { padding-left: 8px; height: 32px; From 6c08b3fadd5c213402bda5bf383d38c5db1900d3 Mon Sep 17 00:00:00 2001 From: Peuuuur-Noel Date: Fri, 10 May 2024 13:57:16 +0200 Subject: [PATCH 8/8] Cosmetics --- .../local/emhttp/plugins/gpustat/gpustatusmovablemulti.page | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page index 7880451..79bb38b 100644 --- a/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page +++ b/src/gpustat/usr/local/emhttp/plugins/gpustat/gpustatusmovablemulti.page @@ -98,6 +98,7 @@ foreach ($multigpus as $id=>$gpu) { $layout _(GPU not available bound to VFIO or inuse in a VM.)_ + EOT; $i++ ; #GPU Number @@ -370,4 +371,4 @@ gpustat_ws.on('message', (data) => { parseStats(JSON.parse(data)); }); gpustat_ws.start(); - \ No newline at end of file +