summaryrefslogtreecommitdiffstats
path: root/tools/gr-regs/analyze_regs.py
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-06 23:02:45 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-06 23:02:45 -0400
commit00765678d59423669fcad6fe56cce9be9bb352e6 (patch)
tree7b06fe7d361f3526f47c92d0f26c483b626c4768 /tools/gr-regs/analyze_regs.py
parentd0a1ca21d24b4d05385d95eefa9930e505206b8f (diff)
downloadopen-iov-00765678d59423669fcad6fe56cce9be9bb352e6.tar.gz
open-iov-00765678d59423669fcad6fe56cce9be9bb352e6.zip
tools: durable BAR0 GR register sampler + analyzer (gr-regs/)
reg_sampler.py: high-rate read-only MMIO sampler for the physical GPU's PGRAPH/FECS/SKED/PFIFO registers (FECS current-context valid + pointer, SKED CWD table occupancy/activity, GRFIFO, FE QMD-virt, PMC_ENABLE) with analyze_regs.py for value distributions and transition timelines. Recorded ground truth and register semantics in tools/gr-regs/README.md. Used to capture the live distro-driver CUDA reference (FECS VALID=1, CWD table 0x3f002000 while running) and to observe the ladder's forwarded launch (CWD entry + SKED processing after the mode-35 lane enable).
Diffstat (limited to 'tools/gr-regs/analyze_regs.py')
-rw-r--r--tools/gr-regs/analyze_regs.py38
1 files changed, 38 insertions, 0 deletions
diff --git a/tools/gr-regs/analyze_regs.py b/tools/gr-regs/analyze_regs.py
new file mode 100644
index 0000000..b03aca4
--- /dev/null
+++ b/tools/gr-regs/analyze_regs.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+import collections, sys
+path = sys.argv[1] if len(sys.argv) > 1 else '/tmp/opencode/regs-m63.txt'
+cmp_mode = len(sys.argv) > 2 and sys.argv[2] == 'cmp'
+hdr = None
+rows = []
+with open(path) as f:
+ for line in f:
+ if line.startswith('#'):
+ if line.startswith('# ts '):
+ hdr = line.split()[2:]
+ continue
+ p = line.split()
+ if len(p) >= 2:
+ rows.append((float(p[0]), p))
+print("samples:", len(rows), "t range", rows[0][0], rows[-1][0])
+cols = collections.defaultdict(collections.Counter)
+h = {n: i for i, n in enumerate(hdr)}
+for t, p in rows:
+ for i, n in enumerate(hdr):
+ if 1 + i < len(p):
+ cols[n][p[1 + i]] += 1
+for n in ('FECS_CURRENT_CTX', 'FECS_NEW_CTX', 'CWD_TABLE_0', 'CWD_TABLE_1',
+ 'SKED_HWW_ESR', 'SKED_ACTIVITY', 'GRFIFO_STATUS', 'FECS_CPUCTL',
+ 'PGRAPH_STATUS', 'PMC_ENABLE'):
+ c = cols.get(n)
+ if c:
+ print('%-22s %s' % (n, ', '.join('%s x%d' % (k, v) for k, v in c.most_common(8))))
+# interesting transitions: where FECS_CURRENT_CTX or CWD_TABLE_0 or GRFIFO change
+print("=== transitions (FECS_CURRENT_CTX / CWD_T0 / GRFIFO) ===")
+last = {}
+for t, p in rows:
+ key = (p[1 + h['FECS_CURRENT_CTX']], p[1 + h['CWD_TABLE_0']], p[1 + h['GRFIFO_STATUS']])
+ if key != last.get('k'):
+ print('t=%8.2f FECS=%s NEW=%s CWD0=%s CWD1=%s SKED_ACT=%s GRFIFO=%s PGRAPH=%s' % (
+ t, key[0], p[1 + h['FECS_NEW_CTX']], key[1], p[1 + h['CWD_TABLE_1']],
+ p[1 + h['SKED_ACTIVITY']], key[2], p[1 + h['PGRAPH_STATUS']]))
+ last['k'] = key