Repository navigation
novatek: the HDAL test under load -- H.265 runs out of time, not order; IVE's driver races itself - #216
Conversation
…r; IVE's driver races itself
Under a loaded host (two suites side by side) the HDAL test failed in
three places. None of them was a wrong picture; guest-error logs and
the encoder's own completion path show no picture dropped, no buffer
full and no H.26x error.
- hd_video_record's tiled H.265: the sample runs for a fixed 6 s, and a
loaded host codes fewer 2880x1620 pictures in that time (3.7..7 KB
when it failed, 8.6..19 KB when it passed); under two pictures, the
check has nothing to see move. run() now holds q until the bitstream
reaches WAIT_BYTES (16000), for up to 40 s more.
- hd_video_encode_only's "decodes to the input, in order": the sample
pushes a frame every 30 ms with a timeout of 0, and drops it ("push_in
error") when the emulated pipeline is behind. Every PSNR-10 failure
had at least one such drop early on: the check aligned the first
picture and then demanded each next input frame, so one drop shifted
every comparison. The check now matches each picture to its input
frame and requires each to be 1..4 frames after the last (still in
order, never backwards); push_in drops are reported apart from HDAL
errors and may be at most a quarter of the pictures. Checked offline:
a clean stream and one with a frame dropped pass, one out of order
fails.
- alg_ive_lut_sample_nonblocking: one thread checked an empty buffer.
Its trigger had been refused ("ive_stateMachine: Operation 2 illegal
in RUN state", "Error to do trigger_internal(), channel=0"), and the
sample does not look at the trigger's result. The race is the vendor
driver's: kdrv_ive_trigger_nonblock -> trigger_internal runs setMode and
ive_start (to RUN) under a semaphore, releases it, returns, and only
then calls ive_pause (out of RUN), so the other channel's thread,
woken by the release, can run setMode in RUN. Silicon's microsecond
setMode makes the threads meet rarely; a loaded host makes it common
(3 of 4 runs of four side by side). The test reruns the sample, up to
three times, only when it failed after such a refusal.
The IVE's jobs now complete ~1 ms after START on the engine timer, as
the other engines' do and as silicon's take, instead of within the
START write; it made no difference to the race (which is between two
pieces of guest code) but is the more faithful timing, and the
non-blocking sample's 0-timeout poll simply retries a job not yet done.
The IVE qtests wait for frame end instead of expecting it at once.
Two full runs side by side: 130/130 each.
PR Summary by QodoStabilize Novatek HDAL tests under load and correct IVE job timing
AI Description
Diagram
High-Level Assessment
Files changed (5)
|
Code Review by Qodo
1.
|
… gets its own frame end Review fix: with the job deferred to the 1 ms timer, a second START in that millisecond (the non-blocking sample's other channel) reprogrammed the registers and re-armed the one timer. The first job then never ran and raised no frame end. The IVE now runs a job as its START is written, with the registers it started with. It counts the frame ends still to raise and raises them 1 ms apart, the first 1 ms after its START, so each accepted job gets its own, in order. The count is reset by the engine's reset and the device's, and migrates (vmstate 3). New qtest: two LUT jobs started back to back with different thresholds and output buffers each write their own result. No frame end is raised at once; one comes, and after it is cleared, the other. Two full runs side by side: 130/130 each.
Under a loaded host (two suites side by side) the HDAL test failed in
three places. None of them was a wrong picture; guest-error logs and
the encoder's own completion path show no picture dropped, no buffer
full and no H.26x error.
loaded host codes fewer 2880x1620 pictures in that time (3.7..7 KB
when it failed, 8.6..19 KB when it passed); under two pictures, the
check has nothing to see move. run() now holds q until the bitstream
reaches WAIT_BYTES (16000), for up to 40 s more.
pushes a frame every 30 ms with a timeout of 0, and drops it ("push_in
error") when the emulated pipeline is behind. Every PSNR-10 failure
had at least one such drop early on: the check aligned the first
picture and then demanded each next input frame, so one drop shifted
every comparison. The check now matches each picture to its input
frame and requires each to be 1..4 frames after the last (still in
order, never backwards); push_in drops are reported apart from HDAL
errors and may be at most a quarter of the pictures. Checked offline:
a clean stream and one with a frame dropped pass, one out of order
fails.
Its trigger had been refused ("ive_stateMachine: Operation 2 illegal
in RUN state", "Error to do trigger_internal(), channel=0"), and the
sample does not look at the trigger's result. The race is the vendor
driver's: kdrv_ive_trigger_nonblock -> trigger_internal runs setMode and
ive_start (to RUN) under a semaphore, releases it, returns, and only
then calls ive_pause (out of RUN), so the other channel's thread,
woken by the release, can run setMode in RUN. Silicon's microsecond
setMode makes the threads meet rarely; a loaded host makes it common
(3 of 4 runs of four side by side). The test reruns the sample, up to
three times, only when it failed after such a refusal.
The IVE's jobs now complete ~1 ms after START on the engine timer, as
the other engines' do and as silicon's take, instead of within the
START write; it made no difference to the race (which is between two
pieces of guest code) but is the more faithful timing, and the
non-blocking sample's 0-timeout poll simply retries a job not yet done.
The IVE qtests wait for frame end instead of expecting it at once.
Two full runs side by side: 130/130 each.
Design record for #200 (squash commit 21fbe55 went in with an empty body)
#200's squash merge, "novatek: the AI turnkey's face recognition network -- frcnn tells Obama from Biden (#200)", lost its message to an empty body file. Its record, from the PR branch's commits:
novatek: the AI turnkey's face recognition network -- frcnn tells Obama from Biden
The v1.01.007 AI turnkey ships CNNLib/para/frcnn/nvt_model.bin and
nothing else: no library, sample, parameters or documentation, in any
SDK release. Its tensor descriptors (the OINF section) say what it is:
input "data" 112x112x3, output "BatchNormalization_fc1_Y" 1x1x128, s16
with 13 fraction bits (fmt 0xa110020d) -- the InsightFace / ArcFace
face embedding, a MobileFaceNet of depthwise layers, PReLU, a global
pooling, a fully connected layer and BN.
qemu-boot/novatek-frcnn-sample.c runs it through vendor_ai_net alone
(the ai_net_with_buf flow), on 112x112 NV12 faces, and writes each
face's 128 values to det_results/fr_features.txt. The turnkey's models
start with 32 bytes of their own (a type word, zeros) before the network
(chip id 4); the detector libraries' version checks step past them, and
without that kflow_ai_net reads chip id 0 and refuses the model.
Running it found four rules the classifier and detectors had not
exercised, and one they had hidden:
from three jobs -- ReLU(-x) by bit 16 (u8), ReLU(x) (u16), and an
element-wise job whose BN scales the first by the negated slopes --
and the model logged bit 16 as unimplemented and skipped the job.
(0xfff44c and the like); pvdcnn's alphas are spread symmetrically
about 0 too (2113 of 32108 with bit 23). Read unsigned, every
frcnn embedding saturated to the same +-4 pattern.
does. Only frcnn's BN + global average writes one; without the 8
bits its output used under 0.5% of s16, against a next BN whose
means expect ~256x more.
x 16), the embedding layer's 512 inputs; without it the FC output
saturates.
width. The rule fitted in novatek: the AI turnkey's detectors -- people, vehicles and faces found #197 (before it for 16-bit outputs) had
been fitted with alpha unsigned. With alpha signed and the bias
after it everywhere, frcnn's same-person similarities are 0.68..0.82
and different people's -0.05..0.18 (with the old rule: all 0.95+, a
grey square included), and pvdcnn finds all three vehicles of the
dashcam frame (truck, white car ahead, small car), where before it
found only the small car. pdcnn now also finds the small facing man
and both Messis; it still misses the man turned away.
test-novatek.py checks each rule at register level. The test data is
face_recognition's example photos (pinned commit): three of Obama, two
of Biden, one each of Alex Lacamoire and Lin-Manuel Miranda. Each face
is aligned to ArcFace's 112x112 template by a similarity transform of
its five landmarks, which alg_fdcnn_ai2_sample gave under QEMU. A
mirrored Obama and a grey square are the controls. test-novatek-hdal.sh
checks that:
pvdcnn's expectation becomes the two people it finds with confidence
(the large Messi, the facing man) and the three vehicles.
Full run with --kmods, the v1.01.007 model and the detectors: 118/118
(the classifier still names the sea snake at 0.514828); without the
samples 44/44; qtests pass.
novatek: frcnn check -- an all-zero embedding is unlike everything
Review fix: cos() divided by the product of the norms, so an all-zero
embedding (an emulation regression, say) raised ZeroDivisionError. That
stopped the one script that prints every turnkey detector's summary, and
pdcnn, pvdcnn, fdcnn and cddcnn would all have failed as "no result"
with frcnn. It now returns 0 for a zero vector; checked with the grey
square's embedding zeroed, which leaves every other result in place.