Skip to content

golden: reference output generator for output verification (Phase 1)#133

Closed
jcelerier wants to merge 2 commits into
mainfrom
feature/golden-output-verification
Closed

golden: reference output generator for output verification (Phase 1)#133
jcelerier wants to merge 2 commits into
mainfrom
feature/golden-output-verification

Conversation

@jcelerier

Copy link
Copy Markdown
Member

First phase of output verification (see OUTPUT_VERIFICATION_PLAN.md): a golden oracle so we can check that every object actually cooks and produces correct output — and, next, that each backend reproduces it.

What

A per-object golden backend mirroring the *_dump target. For each object it instantiates the raw C++ type via the same wrappers the bindings use, feeds deterministic input (controls to mid-range, audio inputs to a bounded per-channel sine, a small test image for CPU texture inputs), runs prepare + process, and writes golden/<c_name>.json with the recorded inputs + outputs + meta. That file is the oracle every backend must reproduce.

  • include/avnd/binding/golden/run.hpp — the offline runner. Ordered {index,name,value} controls (positional fallback for unnamed ports), audio in/out buffers, CPU texture in (synthesized image) / out ({width,height,hash}), no-op host callbacks (request_channels, buffer.upload, worker.request) + sample-accurate control storage so process() never hits an empty std::function / unallocated buffer. try/catch records a status so a bad object never breaks the build.
  • include/avnd/binding/golden/prototype.cpp.in + cmake/avendish.golden.cmake — per-object executable, run at build time → golden/<c_name>.json; a goldens aggregate target; wired into avnd_make_object / _audioplug / _texture / _geometry / _buffer / avnd_make.
  • OUTPUT_VERIFICATION_PLAN.md — the full plan (oracle, JSON schema, phases, determinism strategy).

Result

Census: 109/110 objects build, run, and produce output — 0 errors, 0 crashes. Spot-checked correct: Addition 0.5+0.5→1.0; Lowpass filters the sine; fourses emits its 4-channel ramp; TextureFilter downscales 16×16→1×1; TextureGenerator emits 480×270; the RGBA8 passthrough round-trips its input.

The lone exception is CubeGeometry (a Max-only geometry variant via avnd_make_max; the base CubeGenerator is covered). Geometry mesh output capture is a documented follow-up (those objects cook; their mesh isn't serialized yet).

Next phases (in the plan): TD differential (feed golden inputs, read outputs, diff), then Python / GStreamer / Pd / Max.

🤖 Generated with Claude Code

jcelerier and others added 2 commits July 1, 2026 12:29
Adds a per-object "golden" backend mirroring the *_dump target: it instantiates
the raw C++ object via the same wrappers the bindings use, feeds deterministic
test input (controls to mid-range, audio inputs to a bounded per-channel sine),
runs prepare + process, and writes golden/<c_name>.json with the recorded inputs
and outputs. That file is the oracle every backend binding must reproduce (see
OUTPUT_VERIFICATION_PLAN.md).

- include/avnd/binding/golden/run.hpp: the offline runner. Sets input controls
  (ordered {index,name,value}, positional name fallback for unnamed ports),
  fills audio inputs, wires no-op host callbacks (request_channels, buffer.upload,
  worker.request) + reserves sample-accurate control storage so process() never
  hits an empty std::function / unallocated buffer, then reads output controls
  and audio. try/catch writes a status so a failing object never breaks the build.
- include/avnd/binding/golden/prototype.cpp.in + cmake/avendish.golden.cmake:
  per-object executable, run at build time -> golden/<c_name>.json; a `goldens`
  aggregate target; wired into avnd_make_object / avnd_make_audioplug.
- OUTPUT_VERIFICATION_PLAN.md: full plan (oracle, schema, phases, determinism).

Census: 93/110 objects build, and all 93 run and produce correct output
(verified e.g. Addition 0.5+0.5=1.0, Lowpass filters the sine, fourses emits its
4-channel ramp). The remaining 17 are texture/geometry/GPU/buffer objects that
need a distinct execution+capture path (Phase 1.2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011s7huWR2wFsLFiMJPjx1z2
…ts (Phase 1.2)

- run.hpp: synthesize a small deterministic input image for each CPU texture
  input (so filters have data to read), and record each CPU texture output as
  {width, height, content-hash}. GPU textures are left alone (need a graphics
  context).
- avendish.cmake: emit a golden target from avnd_make_texture / _geometry /
  _buffer and from the BACKENDS-list avnd_make() form, so those objects get an
  oracle too.

Census now: 109/110 objects build, run, and produce output (0 errors, 0
crashes). Verified e.g. TextureFilter downscales 16x16 -> 1x1, TextureGenerator
emits 480x270, the RGBA8 passthrough round-trips its input. The lone exception
is CubeGeometry (a Max-only geometry variant declared via avnd_make_max; the
base CubeGenerator is covered). Geometry mesh *output* capture is still a
follow-up -- those objects cook but their mesh isn't serialized yet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011s7huWR2wFsLFiMJPjx1z2
@jcelerier

Copy link
Copy Markdown
Member Author

Superseded by #137, which combines all outstanding work into a single PR.

@jcelerier jcelerier closed this Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant