Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Nvidia GPU Support #482

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 61 additions & 3 deletions app/server/linux_json_api.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash

#set -x
ECHO=$(type -P echo)
SED=$(type -P sed)
GREP=$(type -P grep)
Expand All @@ -9,10 +9,12 @@ CAT=$(type -P cat)
HEAD=$(type -P head)
CUT=$(type -P cut)
PS=$(type -P ps)
TAIL=$(type -P tail)
NVSMI=$(type -P nvidia-smi)

_parseAndPrint() {
while read data; do
$ECHO -n "$data" | $SED -r "s/\"/\\\\\"/g" | $TR -d "\n";
$ECHO -n "$data" | $SED -r 's/\\//g' | $TR -d "\n";
done;
}

Expand Down Expand Up @@ -100,7 +102,7 @@ cpu_temp() {
#intel
elif [[ "${returnString/"core"}" != "${returnString}" ]] ; then
fromcore=${returnString##*"coretemp"}
$ECHO ${fromcore##*Physical} | $CUT -d ' ' -f 3 | $CUT -c 2-5 | _parseAndPrint
$ECHO ${fromcore##*Physical} | $CUT -d ' ' -f 3 #| $CUT -c 2-5 #| _parseAndPrint
fi
else
$ECHO "[]" | _parseAndPrint
Expand All @@ -109,6 +111,18 @@ cpu_temp() {
esac
}

# Explore sensors -u -j flags for easy output processs
cpu_multi_temp () {
result=$(sensors | grep 'Core' \
| $SED 's/ */ /g' \
| $CUT -d' ' -f1-3 \
| $TR -d '+' \
| $SED "s/°C//g" \
| $AWK -F: '{print "\""$1"\": \""$2"\"," } ' \
)
$ECHO "{" ${result%?} "}" | _parseAndPrint
}

# by Paul Colby (http://colby.id.au), no rights reserved ;)
cpu_utilization() {

Expand Down Expand Up @@ -646,6 +660,50 @@ user_accounts() {
$ECHO [ ${result%?} ] | _parseAndPrint
}



# For list of available properties
# nvidia-smi --help-query-gpu
gpu_temp() {
result=$($NVSMI --query-gpu=temperature.gpu --format=csv \
| $TAIL -n 1 \
)
$ECHO $result | _parseAndPrint
}

gpu_current_mem() {
result=$($NVSMI --query-gpu=memory.total,memory.used,memory.free --format=csv \
| $TAIL -n 1 \
| $AWK '{print "{ \"total\": " ($1) ", \"used\": " ($3) ", \"available\": " ($5) " }" }' \
)
$ECHO $result | _parseAndPrint
}

gpu_info () {
result=$($NVSMI --query-gpu=gpu_name,driver_version,vbios_version,gpu_uuid,gpu_serial,gpu_bus_id,pci.device,pcie.link.gen.current,memory.total --format=csv \
| $TAIL -n 1 \
| $AWK -F ',' 'BEGIN{OFS=","} {print "{ \"GPU Model\": \"" $1 "\"" \
", \"Driver Version\": \"" $2 "\"" \
", \"Bios Version\": \"" $3 "\"" \
", \"UUID\": \"" $4 "\"" \
", \"Serial\": \"" $5 "\"" \
", \"Bus Id\": \"" $6 "\"" \
", \"PCI Link Gen\": \"" $7 "\"" \
", \"PCI Device\": \"" $8 "\"" \
", \"Total Memory\": \"" $9 "\"" " }"\
}')
$ECHO $result | _parseAndPrint
}

gpu_fan_speed() {
result=$($NVSMI --query-gpu=fan.speed --format=csv \
| tail -n 1 \
| cut -d' ' -f1 \
)
$ECHO $result | _parseAndPrint
}


fnCalled="$1"

# Check if the function call is indeed a function.
Expand Down
3 changes: 2 additions & 1 deletion src/js/core/features/navbar/navbar.directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ angular.module('linuxDash').directive('navBar', ['$location', function($location
'basic-info',
'network',
'accounts',
'apps'
'apps',
'gpu'
]

scope.getNavItemName = function(url) {
Expand Down
4 changes: 2 additions & 2 deletions src/js/core/features/plugin/plugin.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

.plugin.chart-plugin {
padding: 0px;
resize: none;
#resize: none;
padding-bottom: 0;
}

Expand All @@ -77,7 +77,7 @@
}

.plugin-body-short {
height: 263px;
height: 294px;
}

.plugin last-update{
Expand Down
13 changes: 12 additions & 1 deletion src/js/core/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function routesFn($routeProvider) {
'<ram-chart sortablejs-id="ram-chart"></ram-chart> ',
'<cpu-avg-load-chart sortablejs-id="cpu-avg-load-chart"></cpu-avg-load-chart> ',
'<cpu-utilization-chart sortablejs-id="cpu-util-chart"></cpu-utilization-chart> ',
'<cpu-temp sortablejs-id="cpu-temp"></cpu-temp> ',
'<cpu-multi-temp-chart sortablejs-id="cpu-multi-temp-chart"></cpu-multi-temp-chart> ',
'<ram-intensive-processes sortablejs-id="ram-intensive-processes"></ram-intensive-processes> ',
'<cpu-intensive-processes sortablejs-id="cpu-intensive-processes"></cpu-intensive-processes> ',
'<disk-space sortablejs-id="disk-space"></disk-space> ',
Expand Down Expand Up @@ -74,6 +74,17 @@ function routesFn($routeProvider) {
'<pm2 sortablejs-id="pm2"></pm2>',
].join(''),
})


.when('/gpu', {
template: [
'<gpu-info sortablejs-id="gpu-info"></gpu-info>',
'<gpu-temp sortablejs-id="cpu-temp"></gpu-temp> ',
'<gpu-ram-chart sortablejs-id="gpu-ram-chart"></gpu-ram-chart> ',
'<gpu-fan-speed-chart sortablejs-id="gpu-fan-speed-chart"></gpu-fan-speed-chart> ',
].join(''),
})

.otherwise({
redirectTo: '/loading'
})
Expand Down
16 changes: 16 additions & 0 deletions src/js/plugins/cpu-multi-temp-chart.directive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
angular.module('linuxDash').directive('cpuMultiTempChart', ['server', function(server) {
return {
restrict: 'E',
scope: {},
template: '\
<multi-line-chart-plugin \
heading="CPU Multi Temp" \
module-name="cpu_multi_temp" \
units="units"> \
</multi-line-chart-plugin> \
',
link: function(scope) {
scope.units = 'ºC'
}
}
}])
37 changes: 37 additions & 0 deletions src/js/plugins/gpu-fan-speed-chart.directive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
angular.module('linuxDash').directive('gpuFanSpeedChart', ['server', function(server) {
return {
restrict: 'E',
scope: {},
template: ' \
<line-chart-plugin \
\
heading="Fan Speed" \
module-name="gpu_fan_speed" \
color="0,255,0" \
\
max-value="max" \
min-value="min" \
refresh-rate="1500" \
\
get-display-value="displayValue" \
metrics="utilMetrics"> \
</line-chart-plugin> \
',
link: function(scope) {
scope.min = 0
scope.max = 100

scope.displayValue = function(serverResponseData) {
return serverResponseData
}

scope.utilMetrics = [{
name: 'Usage',
generate: function(serverResponseData) {
return serverResponseData + ' %'
}
}]

}
}
}])
71 changes: 71 additions & 0 deletions src/js/plugins/gpu-ram-chart.directive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
angular.module('linuxDash').directive('gpuRamChart', ['server', function (server) {
return {
restrict: 'E',
scope: {},
template: '\
<line-chart-plugin \
\
heading="GPU RAM Usage" \
module-name="gpu_current_mem" \
color="0,255,0" \
\
max-value="maxRam" \
min-value="minRam" \
refresh-rate="1000" \
\
get-display-value="gpuRamToDisplay" \
metrics="gpuRamMetrics"> \
</line-chart-plugin> \
',
link: function(scope) {

// get max ram available on machine before we
// can start charting
server.get('gpu_current_mem', function(resp) {
scope.maxRam = resp.total
scope.minRam = 0
})

scope.gpuRamToDisplay = function(serverResponseData) {
return serverResponseData.used
}

var humanizeRam = function (ramInMB) {
var ram = {
value: parseInt(ramInMB, 10),
unit: 'MB',
}

// if ram > 1,000 MB, use GB
if (ram.value > 1000) {
ram = {
value: (ramInMB/1024).toFixed(2),
unit: 'GB',
}
}

return ram.value + ' ' + ram.unit
}

scope.gpuRamMetrics = [{
name: 'Used',
generate: function(serverResponseData) {
var ratio = serverResponseData.used / serverResponseData.total
var percentage = parseInt(ratio * 100)

var usedRam = humanizeRam(serverResponseData.used)
return usedRam + ' (' + percentage.toString() + '%)'
}
},
{
name: 'Available',
generate: function(serverResponseData) {

var availableRam = humanizeRam(serverResponseData.available)
var totalRam = humanizeRam(serverResponseData.total)
return availableRam + ' of ' + totalRam
}
}]
}
}
}])
37 changes: 37 additions & 0 deletions src/js/plugins/gpu-temp.directive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
angular.module('linuxDash').directive('gpuTemp', ['server', function(server) {
return {
restrict: 'E',
scope: {},
template: ' \
<line-chart-plugin \
\
heading="GPU temp" \
module-name="gpu_temp" \
color="0,255,0" \
\
max-value="max" \
min-value="min" \
refresh-rate="1500" \
\
get-display-value="displayValue" \
metrics="utilMetrics"> \
</line-chart-plugin> \
',
link: function(scope) {
scope.min = 0
scope.max = 100

scope.displayValue = function (serverResponseData) {
return serverResponseData
}

scope.utilMetrics = [{
name: 'Temperature',
generate: function (serverResponseData) {
return serverResponseData + ' °C'
}
}]

}
}
}])
4 changes: 4 additions & 0 deletions src/js/plugins/simple-table-data-plugins.directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ var simpleTableModules = [
{
name: 'cronHistory',
template: '<table-data heading="Cron Job History" module-name="cron_history" info="Crons which have run recently."></table-data>'
},
{
name: 'gpuInfo',
template: '<key-value-list heading="GPU Info" module-name="gpu_info" info="/usr/bin/nvidia-smi read-out."></key-value-list>'
}
]

Expand Down