@plasius/gpu-debug 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,332 @@
1
+ # @plasius/gpu-debug
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@plasius/gpu-debug.svg)](https://www.npmjs.com/package/@plasius/gpu-debug)
4
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/Plasius-LTD/gpu-debug/ci.yml?branch=main&label=build&style=flat)](https://github.com/Plasius-LTD/gpu-debug/actions/workflows/ci.yml)
5
+ [![coverage](https://img.shields.io/codecov/c/github/Plasius-LTD/gpu-debug)](https://codecov.io/gh/Plasius-LTD/gpu-debug)
6
+ [![License](https://img.shields.io/github/license/Plasius-LTD/gpu-debug)](./LICENSE)
7
+ [![Code of Conduct](https://img.shields.io/badge/code%20of%20conduct-yes-blue.svg)](./CODE_OF_CONDUCT.md)
8
+ [![Security Policy](https://img.shields.io/badge/security%20policy-yes-orange.svg)](./SECURITY.md)
9
+ [![Changelog](https://img.shields.io/badge/changelog-md-blue.svg)](./CHANGELOG.md)
10
+
11
+ Opt-in GPU debug instrumentation for Plasius WebGPU runtimes. The package tracks
12
+ caller-reported allocations, queue pressure, dispatch samples, and frame-budget
13
+ signals without claiming portable WebGPU exposes authoritative raw hardware
14
+ counters.
15
+
16
+ Apache-2.0. ESM + CJS builds. TypeScript types included.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ npm install @plasius/gpu-debug
22
+ ```
23
+
24
+ ## Browser Demo
25
+
26
+ ```bash
27
+ npm run demo
28
+ ```
29
+
30
+ Then open `http://localhost:8000/gpu-debug/demo/`.
31
+
32
+ `npm run demo` now visualizes debug telemetry against the shared 3D harbor
33
+ scene from the public `@plasius/gpu-shared` package surface, while
34
+ `npm run demo:example` keeps the console example path.
35
+
36
+ ## What It Solves
37
+
38
+ - Exposes tracked GPU allocation totals by owner and category.
39
+ - Records queue depth, dispatch timings, and estimated invocation counts.
40
+ - Records DAG-ready lane depth and dependency-unlock activity when integrations
41
+ supply those samples.
42
+ - Records compact wavefront queue, hit-buffer, and termination summaries
43
+ without dumping raw GPU buffers.
44
+ - Summarizes frame-budget pressure alongside dispatch activity.
45
+ - Accepts optional host-supplied hardware hints such as memory capacity or core
46
+ count when a native or privileged runtime can provide them.
47
+ - Defaults to disabled so clients opt into the overhead explicitly.
48
+ - Keeps analytics/export outside the package; route any remote delivery through
49
+ `@plasius/analytics`.
50
+
51
+ ## Usage
52
+
53
+ ```ts
54
+ import {
55
+ createGpuDebugSession,
56
+ gpuDebugQueueClasses,
57
+ gpuPipelinePhases,
58
+ gpuResourceCategories,
59
+ summarizeWavefrontTelemetry,
60
+ } from "@plasius/gpu-debug";
61
+
62
+ const debug = createGpuDebugSession({
63
+ enabled: true,
64
+ adapter: {
65
+ label: "Apple M3 Max",
66
+ maxComputeInvocationsPerWorkgroup: 1024,
67
+ memoryCapacityHintBytes: 48 * 1024 * 1024 * 1024,
68
+ coreCountHint: 40,
69
+ },
70
+ });
71
+
72
+ console.log(gpuDebugQueueClasses);
73
+ console.log(gpuPipelinePhases);
74
+ console.log(gpuResourceCategories);
75
+
76
+ const releaseParticles = debug.trackAllocation({
77
+ id: "particles.buffer",
78
+ owner: "particles",
79
+ category: "buffer",
80
+ sizeBytes: 8 * 1024 * 1024,
81
+ label: "Particle state",
82
+ });
83
+
84
+ debug.recordQueue({
85
+ owner: "post-processing",
86
+ queueClass: "post-processing",
87
+ depth: 24,
88
+ capacity: 64,
89
+ frameId: "frame-101",
90
+ });
91
+
92
+ debug.recordReadyLane({
93
+ owner: "lighting",
94
+ queueClass: "lighting",
95
+ laneId: "priority-4",
96
+ priority: 4,
97
+ depth: 5,
98
+ capacity: 8,
99
+ frameId: "frame-101",
100
+ });
101
+
102
+ debug.recordDispatch({
103
+ id: "dispatch-101-post",
104
+ owner: "post-processing",
105
+ queueClass: "post-processing",
106
+ jobType: "post.process",
107
+ frameId: "frame-101",
108
+ durationMs: 1.8,
109
+ workgroups: { x: 48, y: 27, z: 1 },
110
+ workgroupSize: { x: 8, y: 8, z: 1 },
111
+ bytesRead: 2_097_152,
112
+ bytesWritten: 1_048_576,
113
+ });
114
+
115
+ debug.recordDependencyUnlock({
116
+ owner: "lighting",
117
+ queueClass: "lighting",
118
+ sourceJobType: "lighting.direct",
119
+ unlockedJobType: "lighting.resolve",
120
+ priority: 2,
121
+ frameId: "frame-101",
122
+ });
123
+
124
+ debug.recordFrame({
125
+ frameId: "frame-101",
126
+ frameTimeMs: 16.9,
127
+ targetFrameTimeMs: 16.67,
128
+ gpuBusyMs: 8.2,
129
+ });
130
+
131
+ debug.recordPipelinePhase({
132
+ owner: "physics",
133
+ pipeline: "simulation",
134
+ stage: "worldSnapshot",
135
+ frameId: "frame-101",
136
+ durationMs: 0.7,
137
+ snapshotAgeFrames: 0,
138
+ snapshotAgeMs: 0,
139
+ });
140
+
141
+ debug.recordWavefrontTelemetry({
142
+ owner: "wavefront",
143
+ queueClass: "render",
144
+ frameId: "frame-101",
145
+ bounceDepth: 0,
146
+ activeRayCount: 128,
147
+ queueCapacity: 256,
148
+ hitBufferCount: 92,
149
+ terminationReasons: [
150
+ { reason: "emissive", count: 10 },
151
+ { reason: "environment", count: 4 },
152
+ ],
153
+ hitKinds: [
154
+ { kind: "triangle", count: 78 },
155
+ { kind: "environment", count: 4 },
156
+ ],
157
+ });
158
+
159
+ const snapshot = debug.getSnapshot();
160
+ console.log(snapshot);
161
+ console.log(summarizeWavefrontTelemetry(snapshot.wavefront));
162
+ releaseParticles();
163
+ ```
164
+
165
+ ## Hardware Counter Policy
166
+
167
+ Portable WebGPU does not currently guarantee authoritative access to:
168
+
169
+ - raw GPU core count,
170
+ - total adapter memory,
171
+ - vendor-specific live occupancy counters.
172
+
173
+ `@plasius/gpu-debug` therefore exposes:
174
+
175
+ - tracked allocations reported by the caller,
176
+ - estimated invocation and workgroup totals from dispatch metadata,
177
+ - queue-depth and frame-budget summaries,
178
+ - DAG-ready lane and dependency-unlock summaries when integrations report them,
179
+ - pipeline phase and snapshot-lag summaries when integrations report them,
180
+ - wavefront queue, hit-buffer, termination, and bounce-depth summaries when
181
+ integrations report compact telemetry,
182
+ - optional hardware hints provided by the host runtime.
183
+
184
+ If a native shell, browser extension, or proprietary platform layer can provide
185
+ accurate hints, pass them in explicitly. Otherwise treat the session snapshot as
186
+ an inferred optimization aid rather than a full hardware profiler.
187
+
188
+ ## API
189
+
190
+ - `createGpuDebugSession(options?)`
191
+ - `estimateDispatchInvocations(sample)`
192
+ - `gpuDebugQueueClasses`
193
+ - `gpuPipelinePhases`
194
+ - `gpuResourceCategories`
195
+ - `summarizeWavefrontTelemetry(snapshot.wavefront)`
196
+
197
+ The exported constants are the docs-first enum contract for integrations that
198
+ need to validate or surface queue classes, pipeline phases, or tracked resource
199
+ categories without importing internal validation helpers.
200
+
201
+ ## Worker and Frame Correlation
202
+
203
+ When worker-based packages use `@plasius/gpu-worker`, prefer passing stable
204
+ metadata and a shared `frameId` through the worker loop telemetry hooks.
205
+
206
+ ```ts
207
+ import { createGpuDebugSession } from "@plasius/gpu-debug";
208
+ import { createWorkerLoop } from "@plasius/gpu-worker";
209
+
210
+ const debug = createGpuDebugSession({ enabled: true });
211
+
212
+ const loop = createWorkerLoop({
213
+ device,
214
+ frameId: () => `frame-${frameNumber}`,
215
+ worker: {
216
+ pipeline: workerPipeline,
217
+ workgroups: [2, 1, 1],
218
+ workgroupSize: 64,
219
+ owner: "particles",
220
+ queueClass: "simulation",
221
+ jobType: "worker.dequeue",
222
+ },
223
+ jobs: [
224
+ {
225
+ pipeline: simulatePipeline,
226
+ workgroupCount: [64, 1, 1],
227
+ workgroupSize: [64, 1, 1],
228
+ owner: "particles",
229
+ queueClass: "simulation",
230
+ jobType: "particles.simulate",
231
+ },
232
+ ],
233
+ telemetry: {
234
+ onDispatch(sample) {
235
+ debug.recordDispatch({
236
+ owner: sample.owner,
237
+ queueClass: sample.queueClass,
238
+ jobType: sample.jobType,
239
+ frameId: sample.frameId,
240
+ workgroups: sample.workgroups,
241
+ workgroupSize: sample.workgroupSize,
242
+ });
243
+ },
244
+ },
245
+ });
246
+
247
+ debug.recordFrame({
248
+ frameId: `frame-${frameNumber}`,
249
+ frameTimeMs,
250
+ targetFrameTimeMs,
251
+ });
252
+ ```
253
+
254
+ This keeps the package local-first: `@plasius/gpu-worker` emits local samples,
255
+ `@plasius/gpu-debug` stores and summarizes them, and any remote export still
256
+ belongs to `@plasius/analytics`.
257
+
258
+ For DAG-enabled integrations, callers can also feed ready-lane and dependency
259
+ unlock data into the same session:
260
+
261
+ ```ts
262
+ debug.recordReadyLane({
263
+ owner: "lighting",
264
+ queueClass: "lighting",
265
+ laneId: "priority-3",
266
+ priority: 3,
267
+ depth: 2,
268
+ capacity: 8,
269
+ frameId: `frame-${frameNumber}`,
270
+ });
271
+
272
+ debug.recordDependencyUnlock({
273
+ owner: "lighting",
274
+ queueClass: "lighting",
275
+ sourceJobType: "lighting.cache",
276
+ unlockedJobType: "lighting.resolve",
277
+ priority: 2,
278
+ frameId: `frame-${frameNumber}`,
279
+ });
280
+
281
+ debug.recordPipelinePhase({
282
+ owner: "physics",
283
+ pipeline: "simulation",
284
+ stage: "worldSnapshot",
285
+ frameId: `frame-${frameNumber}`,
286
+ durationMs: 0.8,
287
+ });
288
+ ```
289
+
290
+ ## Analytics Integration
291
+
292
+ This package does not ship its own analytics client. If snapshots or events need
293
+ to leave the local runtime, route them through `@plasius/analytics`.
294
+
295
+ ## Demo
296
+
297
+ Run the console demo locally:
298
+
299
+ ```bash
300
+ npm run demo
301
+ ```
302
+
303
+ See [demo/README.md](./demo/README.md) for details.
304
+
305
+ ## Development Checks
306
+
307
+ ```bash
308
+ npm run lint
309
+ npm run typecheck
310
+ npm run test:coverage
311
+ npm run build
312
+ npm run pack:check
313
+ ```
314
+
315
+ ## Release Automation
316
+
317
+ GitHub Actions now carries the package delivery path:
318
+
319
+ - CI runs on pushes and pull requests to enforce lint, typecheck, audit, build,
320
+ coverage, and package verification.
321
+ - CD publishes to npm only through the manual GitHub workflow.
322
+ - A scheduled workflow opens monthly npm audit-fix pull requests.
323
+
324
+ ## Files
325
+
326
+ - `src/types.ts`: public debug types and snapshot contracts.
327
+ - `src/session.ts`: opt-in debug session runtime and summary generation.
328
+ - `src/validation.ts`: shared runtime validation helpers.
329
+ - `tests/*.test.ts`: unit coverage for session behavior and bounded histories.
330
+ - `docs/adrs/*`: package architecture decisions.
331
+ - `docs/tdrs/*`: implementation design records.
332
+ - `docs/design/*`: integration and NFR design detail.