Add golden store publish scripts + nightly CI wiring - #703
Draft
yuhuchua-qti wants to merge 15 commits into
Draft
Conversation
yuhuchua-qti
force-pushed
the
dev/yuhuchua/qnn-ut-golden-publish
branch
2 times, most recently
from
August 18, 2026 05:55
e434afc to
e45fe62
Compare
Flatten onnxruntime/test/providers/qnn/ into tier-first siblings: component/, snapshot/, session_snapshot/, accuracy/, integration/, with shared infra in test_infra/. - Migrate Clip op to spec-shared tiers (one op spec set drives component dtype-dispatch, snapshot + session_snapshot graph goldens, and accuracy inference checks) - Add OpBuilderTestContext: stub-backed QnnModelWrapper factory shared by the component + snapshot tiers - Goldens are NOT committed: the harness reads them from $QNN_UT_SNAPSHOT_GOLDEN_DIR (Artifactory-fetched). Unset/absent -> snapshot skips (GOLDEN_ABSENT) and accuracy always runs -> safe baseline that can never red the build on golden freshness - Golden path logic anchored on /providers/qnn/ with per-tier prefix - CMake tier globs; generate_coverage.sh is the single CI coverage orchestrator running three phases (component -> snapshot -> accuracy) into one lcov capture, with component + accuracy gating and snapshot non-gating (drift is a routing signal). run_snapshot_accuracy.sh is the local-only two-pass runner Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…y.sh The flag writes golden files from scratch regardless of whether they previously exist. "generate" reflects the actual semantics (create from nothing) better than "update" (which implies modifying existing state). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…lain naming
gcov shows two integration tests, Clip_U8/U16_FloatData_QDQConstMinMax,
are the only cases (old or new) that hit clip_op_builder.cc:45-52's
folded-constant fallback. The existing quantized-min/max test cases
look similar but don't hit it — their min/max keep a quant_param on
the initializer and go through the QUANT switch instead. Add a spec +
snapshot + accuracy suite that replays the qdq_constant_folding
end-state (via AddTensorWrapper + MarkTensorAsFoldedConstant) to
cover the gap.
Also reback Clip_{4D_f32_DefaultMinMax,5D_f32} to HTP (QnnCpu dropped
from the wheel; HtpOpDefSupplement confirms RELUMINMAX supports FP32
rank 5, no code change needed — both PASS), and drop the `Plain`
suffix from the default spec/suites/helpers since it read as an
unnecessary negative marker.
51 Clip unit tests: 35 PASS, 16 GOLDEN_ABSENT skips (snapshot tier,
no golden store configured), 0 failures.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tier-first names (QnnUnit_Snapshot_ClipQDQFloatTest) glue the variant onto the op with no delimiter, so tooling that recovers the op segment from the suite name (run_snapshot_accuracy.sh --filter, generate_coverage.sh) cannot split "ClipQDQFloat" back into op=Clip. This caused run_snapshot_accuracy.sh --filter=Clip to match 0 tests in CI. Switch to QnnUnit_<Op>_<Tier>[_<Variant>]Test: the op is recovered as the segment(s) between "QnnUnit_" and the first tier token (Component/ Snapshot/SessionSnapshot/Accuracy), so op names containing underscores (e.g. Gelu_Fusion) stay unambiguous and per-op filters are a clean prefix (QnnUnit_Clip_*). Verified via a fresh coverage build: all four Clip tiers run under their new names (component/accuracy PASS, snapshot SKIPPED pending an external golden store as before), and run_snapshot_accuracy.sh --filter=Clip now matches all 16 snapshot cases across 5 suites (previously 0).
yuhuchua-qti
force-pushed
the
dev/yuhuchua/migrate-clip-ut
branch
from
August 19, 2026 09:13
e65be32 to
7c7bbb7
Compare
…blishing PR2 of the QNN EP UT migration stack. Adds: - resolve_tool_versions.sh: single source of truth for QAIRT + ORT runtime version strings (file-only detection, no env override). Dual-mode (sourceable + executable). Shared by the manifest writer and the future accuracy gate reader. - publish_goldens.sh: thin orchestrator that regenerates goldens, selects only accuracy-PASSING op groups, packages them with a version-stamped manifest.json, and uploads to Artifactory (default dry-run). - pytest suite (17 tests) covering version resolution precedence, sdk.yaml parsing variants, undeterminable exit codes, and edge cases. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Follows the PR1 rename of --update-goldens to --generate-goldens in run_snapshot_accuracy.sh. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move the pass-group selection logic from an inline bash heredoc in publish_goldens.sh into filter_accuracy_pass_groups.py. This makes the classification logic independently testable and reusable by the future accuracy gate (PR4). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds the CI half of PR2 (merged PR2+PR3): a scheduled job that runs publish_goldens.sh to refresh the Artifactory golden store nightly. - qualcomm-internal-golden-publish.yml: reusable workflow (workflow_call + workflow_dispatch) that builds a coverage-instrumented binary, then runs publish_goldens.sh. Inputs: filter, repo_subpath, skip_regen, dry_run. dry_run defaults true so a manual dispatch never clobbers the shared store by accident; the scheduled producer opts into the real upload explicitly. - qualcomm-internal-release-nightly.yml: adds a parallel golden-publish job on the 9am cron, passing dry_run=false. - build_and_test.py: adds coverage_build_linux_x86_64 (coverage build only, no HTML report). publish_goldens.sh does its own golden regen + accuracy verify, so the job needs the instrumented binary but not the report, avoiding a wasted second test run. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Golden stores live under qnn-ep-test-store/, grouped by subject: ut-snapshot/ (this suite) and, later, modelzoo/. Retention keys off the path segment, not the top folder: qnn-ep-test-store/<subject>/latest/ -> never pruned (gates read it) qnn-ep-test-store/<subject>/archive/ -> pruned after 10d - expired_golden_artifacts.json: AQL matching qnn-ep-test-store/*/archive/* created before 10d. latest/ and any permanent data (no archive/ segment) are never matched, so retention can't strand a store without a golden. - qualcomm-internal-clean-artifacts.yml: new "Delete old golden archives" step on the existing nightly cleanup cron. - publish_goldens.sh / golden-publish.yml: repo_subpath default moves from qnn-ut-goldens to qnn-ep-test-store/ut-snapshot. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PR1 renamed accuracy suites from QnnUnit_Accuracy_<Group>Test to QnnUnit_<Group>_Accuracy[_<Variant>]Test. The old regex no longer matched any suite, so publish_goldens.sh would always find zero passing groups. Update the regex and its two doc comments to match the new naming; verified against a synthetic gtest JSON report.
No CI workflow ever exports QAIRT_SDK_ROOT/QNN_SDK_ROOT/SNPE_ROOT/ ORT_PREBUILT_ROOT, so the old env-var-based resolver always fails with "version undeterminable" in real CI. CMakeCache.txt already records the actual onnxruntime_QNN_HOME/onnxruntime_ORT_HOME used by the build (or _deps/ort_core-src when ORT is FetchContent-ed), so read from there instead.
Temporary wrapper: on push to the PR2 branch, run golden-publish in dry-run (nothing touches Artifactory) and upload the packaged zip as a downloadable artifact. Passes dry_run + filter explicitly because a push event has no inputs context. DELETE THIS COMMIT BEFORE MERGE. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The wrapper called golden-publish.yml (which requests checks: write) with default token permissions, causing a startup_failure. Match the reusable workflow's permissions. DELETE WITH THE OTHER TEMP COMMIT BEFORE MERGE. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Lets a golden-publish run also surface the packaged goldens.zip as a downloadable GitHub Actions artifact, gated behind keep_zip_artifact (off by default) for manual inspection.
Verify the new --keep-zip flag end-to-end on the next push before merge.
yuhuchua-qti
force-pushed
the
dev/yuhuchua/qnn-ut-golden-publish
branch
from
August 20, 2026 05:11
b0154fa to
a8010de
Compare
yuhuchua-qti
force-pushed
the
dev/yuhuchua/migrate-clip-ut
branch
3 times, most recently
from
August 31, 2026 07:30
0407fe9 to
7717d38
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stacked on PR1 (
migrate-clip-ut, #399). Delivers the producer side of the QNN EP unit-test golden pipeline: scripts that regenerate goldens, keep only accuracy-passing op groups, version-stamp them, and publish to Artifactory — plus the nightly CI job that runs it and the retention policy that prunes old archives.Pure additive. No production op-builder / snapshot / accuracy source is touched. The consumer (per-PR accuracy-routing gate) is a separate later PR.
What's in it
Version resolver — single source of truth
qcom/scripts/linux/resolve_tool_versions.sh— source-able and executable. Resolves QAIRT version (fromsdk.yamlacrossQAIRT_SDK_ROOT/QNN_SDK_ROOT/SNPE_ROOT) and ORT runtime version (from$ORT_PREBUILT_ROOT/VERSION_NUMBER, then/VERSION). Deliberately does not read repo-rootVERSION_NUMBER(that's the plugin/wheel version, not the ORT runtime). Undeterminable → exit 3 (graceful), so callers treat it as a safe signal. Writer and future gate stay consistent by sharing this code, never a process.Publisher — thin orchestrator
qcom/scripts/linux/publish_goldens.sh— regen goldens viarun_snapshot_accuracy.sh --generate-goldens→ read the accuracy report → package only groups whose everyQnnUnit_Accuracy_<Group>Testcase PASSED → write a version-stampedmanifest.json→ upload a write-oncearchive/<date>-<sha>/and the mutablelatest/pointer. Default is dry-run;--publishis required to actually upload (it overwrites the sharedlatest/pointer — never implicit).qcom/scripts/linux/filter_accuracy_pass_groups.py— extracted pass-group selection (a group passes iff all its accuracy cases COMPLETED with no failures).Nightly CI wiring
.github/workflows/qualcomm-internal-golden-publish.yml— reusable workflow (workflow_call+workflow_dispatch). Builds the coverage-instrumented binary, then runspublish_goldens.sh.dry_rundefaults true so manual dispatch never clobbers the shared store; the scheduled producer opts into the real upload explicitly..github/workflows/qualcomm-internal-release-nightly.yml— adds agolden-publishjob (9am UTC cron) passingdry_run: false.qcom/build_and_test.py— newcoverage_build_linux_x86_64task (coverage build only, no HTML report — snapshot/accuracy tiers only compile under--enable-coverage).Golden store layout + retention
qnn-ep-test-store/ut-snapshot/{archive,latest}/. Theqnn-ep-test-store/parent is shared with future siblings (e.g. modelzoo goldens).qcom/scripts/artifactory/aql/expired_golden_artifacts.json— AQL that matchesqnn-ep-test-store/*/archive/*older than 10d. Retention keys off thearchive/segment only, solatest/pointers (and any permanent data outsidearchive/) are never matched — retention can never leave a store without a current golden..github/workflows/qualcomm-internal-clean-artifacts.yml— new "Delete old golden archives" step (runs on the existing daily cleanup cron, 1h before the publish cron).Test plan
pytest qcom/scripts/linux/tests— 17 tests pass (resolver priority order, sdk.yaml variants, undeterminable → exit 3).publish_goldens.shdry-run end-to-end against a real coverage build-dir: regen → parse accuracy report → stage passing groups → buildgoldens.zip+manifest.json→ prints the twojf rt uploadcommands without executing.manifest.jsonqairt_version/ort_versionmatchresolve_tool_versions.sh both;git_shamatchesgit rev-parse --short=10 HEAD.🤖 Generated with Claude Code