#!/usr/bin/env bash
# gpustream - compact one-line-per-tick GPU stream (passive). For piping/logging.
set -u
RAIL=/sys/kernel/debug/gpu_rail_mv
CLIENTS=/sys/kernel/debug/dri/206400000.gpu/clients
SECS=${SECS:-45}; PER=${PER:-15}; GAP=${GAP:-0.04}
mv2mhz(){ awk -v v="$1" 'BEGIN{n=split("400 0 596 396 631 528 681 720 771 924 862 1128 934 1278",a," ");
  if(v<450){print 0;exit} b=1e9; for(i=1;i<=n;i+=2){d=a[i]-v;if(d<0)d=-d;if(d<b){b=d;f=a[i+1]}} print f}'; }
end=$(( $(date +%s) + SECS ))
printf "time      util  clock      state   GPU contexts\n"
while [ "$(date +%s)" -lt "$end" ]; do
  busy=0; mx=0
  for ((i=0;i<PER;i++)); do mv=$(cat "$RAIL" 2>/dev/null); mv=${mv:-0}
    if [ "$mv" -gt 450 ]; then busy=$((busy+1)); [ "$mv" -gt "$mx" ] && mx=$mv; fi; sleep "$GAP"; done
  util=$(( busy*100/PER )); mhz=$(mv2mhz "$mx"); st=idle; [ "$util" -gt 0 ] && st=ACTIVE
  ctx=$(awk 'NR>1&&$1!=""' "$CLIENTS" 2>/dev/null | wc -l)
  procs=$(awk 'NR>1&&$1!=""{print $1}' "$CLIENTS" 2>/dev/null | sort | uniq -c | awk '{printf "%s(%s) ",$2,$1}')
  printf "%s  %3d%%  %4d MHz  %-6s  %d %s\n" "$(date +%H:%M:%S)" "$util" "$mhz" "$st" "$ctx" "${procs:-—}"
done
