Stock CTC Runtime Sequence
This is the normalized dynamic sequence for
/data/waved/waved-npu-probe.poc --run-stock-ctc.
It combines:
- explicit
[npu:N]markers emitted by the probe; - loaded paths and syscalls observed by
strace 5.9; - metadata-only request records from the
ioctlinterposer; - PoC 1’s static NN SDK call graph;
- PoC 2’s parsed NBG metadata.
No pointer, timestamp, file descriptor, tensor content, model byte, or command-union payload appears here.
End-to-end view
Section titled “End-to-end view”waved-npu-probe │ ├─ validate stock CTC NBG │ v2, target 0x1000000e │ input FP16 [256, 16, 1] │ output FP32 [5200, 16, 1] │ ├─ libnnsdk.so │ aml_module_create / input_set / output_get / destroy │ ├─ libovxlib.so + libOpenVX.so │ NBG graph setup and execution │ ├─ libGAL.so │ 73 × ioctl(request 30000, 376-byte interface) │ ├─ /dev/galcore │ allocation, lock, commit, event, signal, unlock, release │ └─ VIP core 0 three deterministic executionsPhase map
Section titled “Phase map”Phase 1 — reachability
Section titled “Phase 1 — reachability”Probe marker:
[npu:1] open /dev/galcore O_RDWRObserved:
openat("/dev/galcore", O_RDWR|O_CLOEXEC) = successclose("/dev/galcore") = successThis proves only that the process can reach the driver. No HAL ioctl occurs
because the Rust OpenOptions handle is immediately dropped.
Phase 2 — read-only status
Section titled “Phase 2 — read-only status”Probe marker:
[npu:2] read NPU status (read-only)Observed reads:
/sys/module/galcore/parameters/nanoqFreq = 838860800/sys/module/galcore/parameters/enableNN = 255No HAL ioctl occurs.
Phase 3 — model validation
Section titled “Phase 3 — model validation”Probe marker:
[npu:3] read and validate /model/asr_de/de_online/ctc_online.nbThe exact 2,810,984-byte model is opened and hashed. PoC 2 parses it as:
NBG version: 0x00020000product: 0x1000000einput: FP16 [256, 16, 1]output: FP32 [5200, 16, 1]No HAL ioctl occurs.
Phase 4 — NN SDK and metadata
Section titled “Phase 4 — NN SDK and metadata”Probe marker:
[npu:4] load libnnsdk.so and query NBG tensor metadataThe dynamic path reaches libnnsdk.so; tensor metadata agrees with PoC 2.
No HAL ioctl occurs. This supports PoC 1’s static finding that the metadata
helpers parse graph metadata without creating a live device graph.
Phase 5 — graph creation
Section titled “Phase 5 — graph creation”Probe marker:
[npu:5] create graph from firmware NBG memoryDriver events:
open /dev/galcore → successopen /dev/galcore1 → ENOENTThe exact 46-command sequence is:
01 VERSION02 CHIP_INFO03 QUERY_VIDEO_MEMORY hardware 3D04 QUERY_CHIP_IDENTITY hardware VIP05 QUERY_CHIP_OPTION hardware VIP06 ATTACH hardware VIP07 USER_SIGNAL hardware VIP08 GET_BASE_ADDRESS hardware VIP09 USER_SIGNAL10 USER_SIGNAL11 ALLOCATE_LINEAR_VIDEO_MEMORY12 LOCK_VIDEO_MEMORY13 USER_SIGNAL14 USER_SIGNAL15 ALLOCATE_LINEAR_VIDEO_MEMORY16 LOCK_VIDEO_MEMORY17 USER_SIGNAL
18 QUERY_CHIP_IDENTITY19 QUERY_CHIP_OPTION20 ATTACH21 USER_SIGNAL22 GET_BASE_ADDRESS23 USER_SIGNAL24 USER_SIGNAL25 ALLOCATE_LINEAR_VIDEO_MEMORY26 LOCK_VIDEO_MEMORY27 USER_SIGNAL28 USER_SIGNAL29 ALLOCATE_LINEAR_VIDEO_MEMORY30 LOCK_VIDEO_MEMORY31 USER_SIGNAL
32 QUERY_CHIP_OPTION33 ALLOCATE_LINEAR_VIDEO_MEMORY34 LOCK_VIDEO_MEMORY35 ALLOCATE_LINEAR_VIDEO_MEMORY36 LOCK_VIDEO_MEMORY37 ALLOCATE_LINEAR_VIDEO_MEMORY38 LOCK_VIDEO_MEMORY39 ALLOCATE_LINEAR_VIDEO_MEMORY40 LOCK_VIDEO_MEMORY41 ALLOCATE_LINEAR_VIDEO_MEMORY42 LOCK_VIDEO_MEMORY43 ALLOCATE_LINEAR_VIDEO_MEMORY44 LOCK_VIDEO_MEMORY45 ALLOCATE_LINEAR_VIDEO_MEMORY46 LOCK_VIDEO_MEMORYThe two similar initialization groups may represent separate OpenVX/GAL objects or devices within the userspace stack. The trace proves the repeated shape, not the owning object identity, because handles and union payloads are not captured.
By the end of phase 5:
- the generic GAL version and chip queries passed;
- VIP hardware type 4, core 0 is selected;
- two VIP attach/base-address initialization groups passed;
- 11 linear video-memory allocations are locked;
- the graph is ready without a commit yet.
Phase 6 — input submission
Section titled “Phase 6 — input submission”Probe marker:
[npu:6] submit deterministic zero-filled inputsObserved HAL calls:
noneFor this graph and INPUT_TYPE_BINARY_RAW, aml_module_input_set does not
create a separately visible driver transaction. The most conservative
interpretation is that it copies or binds input into storage prepared in
phase 5. Other input modes remain uncharacterized.
This matters for streaming audio: a production wrapper may be able to update an already-bound frame buffer without a graph-recreation ioctl sequence, but that must be verified with a custom graph and real repeated frames.
Phase 7 — three executions
Section titled “Phase 7 — three executions”Probe marker:
[npu:7] execute and hash 3 deterministic iterationsEach iteration emits the identical three-call group:
COMMIT → EVENT_COMMIT → USER_SIGNALExpanded:
47 COMMIT48 EVENT_COMMIT49 USER_SIGNAL
50 COMMIT51 EVENT_COMMIT52 USER_SIGNAL
53 COMMIT54 EVENT_COMMIT55 USER_SIGNALAll are hardware type VIP, core 0, syscall result zero, HAL status zero. Each iteration returns one 332,800-byte output with the same digest.
This is the runtime signature a future verified tiny custom graph should match at the command-family level. It is not a packet template and must not be replayed.
Phase 8 — graph destroy and process teardown
Section titled “Phase 8 — graph destroy and process teardown”Probe marker:
[npu:8] destroy graph and release runtime resourcesObserved:
56 UNLOCK_VIDEO_MEMORY57 RELEASE_VIDEO_MEMORY58 UNLOCK_VIDEO_MEMORY59 RELEASE_VIDEO_MEMORY60 UNLOCK_VIDEO_MEMORY61 RELEASE_VIDEO_MEMORY62 UNLOCK_VIDEO_MEMORY63 RELEASE_VIDEO_MEMORY64 UNLOCK_VIDEO_MEMORY65 RELEASE_VIDEO_MEMORY66 UNLOCK_VIDEO_MEMORY67 RELEASE_VIDEO_MEMORY68 UNLOCK_VIDEO_MEMORY69 RELEASE_VIDEO_MEMORY
70 COMMIT71 EVENT_COMMIT72 USER_SIGNAL73 UNLOCK_VIDEO_MEMORYThe probe then reports:
aml_module_destroy status=0RESULT: PASSexit_group(0)There is no observed DETACH command or explicit close of the runtime’s
/dev/galcore descriptor before process exit. In this disposable probe,
process teardown owns the final descriptor/context cleanup. A long-lived
waved integration must test context reuse and explicit shutdown rather than
assuming process exit.
Loaded library path
Section titled “Loaded library path”Relevant first-successful opens:
probe├─ libnnsdk.so│ ├─ librt.so.1│ └─ libovxlib.so│ ├─ libOpenVX.so│ ├─ libVSC_Lite.so│ ├─ libm.so.6│ ├─ libVSC.so│ ├─ libGAL.so│ ├─ libArchModelSw.so│ ├─ libNNArchPerf.so│ └─ libstdc++.so.6└─ normal glibc support DSOsThis is a load-order observation, not a complete ownership tree. A DSO may be
opened because another DSO declares it, because code calls dlopen, or
because the loader resolves a transitive dependency.
The coexistence of libVSC*, libArchModelSw, and a precompiled NBG is a
useful PoC 5 lead. It is not enough to claim that a compiler API or correct
product profile is available.
System-call envelope
Section titled “System-call envelope”Both acceptance runs had identical selected syscall counts:
| Syscall | Count | Role |
|---|---|---|
execve |
1 | Start stock probe |
openat |
66 | Loader, model, sysfs, and driver opens |
close |
22 | Explicit file closes |
mmap |
69 | Loader and anonymous process mappings |
mprotect |
181 | Loader protections and memory guards |
munmap |
10 | Userspace mapping release |
brk |
3 | Heap boundary |
clone |
1 | Probe worker thread |
futex |
4 | Rust/thread synchronization |
ppoll |
1 | Runtime startup check |
ioctl |
73 | GAL interface transactions |
write |
178 | Probe diagnostics plus metadata-only tracer records |
exit_group |
1 | Normal process exit |
The selection intentionally excludes read and model/tensor payloads.
Implications for a noise-suppression runtime
Section titled “Implications for a noise-suppression runtime”PoC 3 removes uncertainty below the graph API:
- the exact stock path reaches VIP hardware type 4 through
/dev/galcore; - graph setup, frame execution, and teardown have stable visible boundaries;
- repeated execution reuses the graph and memory setup;
- input submission did not recreate or submit the graph;
- one execute costs one commit/event/signal group at the observed interface;
- cleanup can be checked independently of output quality.
Still required before an NPU denoiser:
- produce a legitimate product-
0x1000000egraph; - verify its operations, dtypes, layouts, and recurrent-state behavior;
- bind real streaming frames and prove that input/output updates remain bounded;
- measure deadline, quality, memory, thermals, and sustained stability;
- keep the existing CPU denoiser as fallback;
- test explicit long-lived context shutdown without relying on process exit.
The phase-7 signature is a validation reference, not a shortcut around those gates.