Parity harness#
The parity harness proves that each dynG port computes exactly what its original computes, and
records how fast it does it (PLAN Sections 6.3 and 8.3; the decisions are in
ADR 0013). The original repositories are never
modified, built in place or checked out: they are only read with git archive.
All generated artifacts live in the persistent work area $DYNG_SCRATCH (default
~/Projects/dyng-work, set by scripts/dev_env.sh), never in the repository:
$DYNG_SCRATCH/
ref/<name>@<commit7>/{unpatched,patched}/ scratch copies (build_reference.sh)
ref/<name>@<commit7>/archive-check.txt what the archive needs from outside
goldens/<set>/ golden cases + MANIFEST.sha256 (export_goldens.py)
bench/mosp/<graph>/ benchmark inputs (perf_ab.py prepare)
perf.lock exclusive lock of every performance measurement
Files#
File |
Purpose |
|---|---|
|
the pinned originals: commit, |
|
|
|
the additive export patch: builds the exporters of |
|
|
|
the CBST trace recorders of ESCHER-GPU@abcf9b2 and MOSP_ESCHER@4b86159 (M8a, ADR 0036): |
|
|
|
the paper-scale |
|
the |
|
the CBST trace goldens of M8a (ADR 0036): |
|
reader of the CBST traces (format 1): |
|
the container-level replay of M8b ( |
|
the memory gate and the maintain reading of the hypergraph against ESCHER-GPU (`perf_ab.py hypergraph memory |
|
the cross-check of the two ESCHER cores (PLAN 6.3 step 2): |
|
the OpenMP A/B of |
|
writes the |
|
GENERATED manifest: the SHA-256 of each golden set’s |
|
verifies the goldens, then replays every case through |
|
the original’s timers -> dynG profiler stages (written before each port); |
|
|
|
the benchmark suites of |
|
the mutation checks of PLAN 8.4 against the golden suites, each on the sequential, OpenMP and CUDA backends: sssp (the skipped subtree invalidation), cycle_count (CycleEnumeration-GPU’s double-counted 5-cycles and weakened ownership rule, host and device) and mosp (a combined-edge weight from one tree only; path costs from one objective’s weights); and the GoogleTest suites of the ESCHER store (cbst, M8a: 7 mutations), the hypergraph container (hypergraph, M8b: the h2v insert payload not deduplicated, the host allocator’s tie rule reversed, the line-graph mirror additions dropped) and the conformance kit’s hypergraph axis (kit, M8b: the frontier from requested ids). Each mutation is applied to a |
|
the release certificate (PLAN 8.3): |
|
reads the records of a dynG-against-dynG A/B by ADR 0024: every gated region’s ratio of medians with its bootstrap interval, and a bimodal region by its within-mode ratios and the Fisher test of equal mode fractions; exit 1 if a region is outside the bar |
|
one-off diagnostics, not gates: |
|
the idle helper through which |
|
smoke tests of the scripts (pytest; run by |
|
scripts that regenerate the small committed test fixtures ( |
|
the committed parity and performance records, one per milestone (a release’s certificate is |
Typical session#
The harness reads each original from a clone in $DYNG_ORIGINALS_DIR/<name> (default
~/Projects/<name>); clone the ones you need once from their upstream in references.toml,
for example git clone https://github.com/SMShovan/MOSP-OpenMP.git ~/Projects/MOSP-OpenMP.
source scripts/dev_env.sh
parity/build_reference.sh --test # build (and test) every pinned original
parity/export_goldens.py --twice # write the goldens; prove the export is reproducible
cmake --preset parity && cmake --build --preset parity
ctest --preset parity -L parity # golden replay (skipped without goldens)
parity/compare.py --exe build/parity/tools/compat/dyng-compat-mosp --json out.json
parity/compare.py --driver original --ref "$DYNG_SCRATCH/ref/MOSP-CUDA@e220ee2/patched"
cmake --preset parity-cuda && cmake --build --preset parity-cuda
parity/compare.py --exe build/parity-cuda/tools/compat/dyng-compat-mosp --configs cuda
parity/perf_ab.py prepare --graph roadNet-CA # inputs, as the original's bench/prepare.sh
flock "$DYNG_SCRATCH/perf.lock" parity/perf_ab.py run --graph roadNet-CA \
--exe build/parity/tools/compat/dyng-compat-mosp --runs 21 --json out.json
# graphs of the sssp gate (PLAN 6.4.2): roadNet-PA, roadNet-CA, rgg, road_usa_g
# cycle_count (M2a): goldens, replay, OpenMP gate against CycleEnumeration-GPU@0a976ad
parity/export_goldens.py cycle_count --twice
parity/compare.py cycle_count --exe build/parity/tools/compat/dyng-compat-cycle-enum
flock "$DYNG_SCRATCH/perf.lock" parity/perf_ab.py cycle_count run \
--exe build/parity/tools/compat/dyng-compat-cycle-enum --runs 11 --json out.json
flock "$DYNG_SCRATCH/perf.lock" parity/perf_ab.py run --backend cuda --gpu 0 --graph roadNet-CA \
--exe build/parity-cuda/tools/compat/dyng-compat-mosp --runs 21 --json out.json
# mosp (M7): the paper-scale goldens, the K sweep input, the gates (timed_regions/mosp.toml)
parity/perf_ab.py prepare --graph roadNet-CA-K4 --widen roadNet-CA:4
parity/export_goldens.py mosp_scale
parity/compare.py mosp_scale --exe build/parity/tools/compat/dyng-compat-mosp --configs openmp:28,sequential
flock "$DYNG_SCRATCH/perf.lock" parity/perf_ab.py mosp --backend cuda --gpu 0 --graph roadNet-CA \
--exe build/parity-cuda/tools/compat/dyng-compat-mosp --runs 21 --json out.json
# the ESCHER CBST store (M8a): reference builds and recording twins, traces, cross-check
parity/build_reference.sh --fresh --test ESCHER-GPU MOSP_ESCHER
parity/exporters/escher/cbst_census.py ESCHER-GPU && parity/exporters/escher/cbst_census.py MOSP_ESCHER
parity/exporters/escher/check_twins.py ESCHER-GPU # twins print what the originals print
parity/cbst_trace_goldens.py datasets # coauth-DBLP variants (datasets/registry.toml)
parity/export_goldens.py cbst_trace all --twice
parity/escher_trace.py summary <trace.cbt>
parity/escher_crosscheck.py run --set cbst_trace_escher_gpu_test --store MOSP_ESCHER --capacity-floor 67108864
# the hypergraph container (M8b): id, row and line-graph parity, memory gate, maintain reading
cmake --preset parity-cuda && cmake --build --preset parity-cuda --target dyng_hypergraph_ids_tool
parity/compare.py hypergraph_ids --backend cuda --set escher_gpu_test --set mosp_escher_test \
--exe build/parity-cuda/cpp/tests/dyng_hypergraph_ids --jobs 8 --certificate out/
parity/compare.py hypergraph_ids --backend openmp --threads 8 --set escher_gpu_coauth50k
parity/compare.py hypergraph_ids --backend cuda --line-graph --mode by_id --set escher_gpu_syn1m
flock "$DYNG_SCRATCH/perf.lock" parity/perf_ab.py hypergraph memory --gpu 0
flock "$DYNG_SCRATCH/perf.lock" parity/perf_ab.py hypergraph maintain --gpu 0 --runs 5
Re-exporting the hypergraph sets#
The container-level replays read the CBST trace goldens of M8a ($DYNG_SCRATCH/goldens/ cbst_trace/<set>, pinned by [sets.cbst_trace_<set>] of goldens.toml); nothing of M8b is
exported on its own. To re-create them on a new machine:
parity/build_reference.sh --fresh ESCHER-GPU MOSP_ESCHER(the committed treesabcf9b2and4b86159only; MOSP_ESCHER’s uncommitted working tree is never read) andparity/exporters/escher/relink_twins.sh(the recording twins, ADR 0036);parity/cbst_trace_goldens.py datasets(the coauth-DBLP variants ofdatasets/registry.toml, re-derived and checked by SHA-256;datasets/preprocess/benson_to_hg.pywrites both);parity/export_goldens.py cbst_trace all --twice: every set exported twice from two fresh copies, compared, and written togoldens.toml(a set whose manifest digest changes is a new golden set: review the diff before committing it);parity/cbst_trace_goldens.py subsetandparity/escher_trace.py extract-batches <trace> <file> [--sessions N]re-write the committed subsets (cpp/tests/data/goldens/cbst_trace,.../hypergraph_batches, whoseSUBSET.txtlists the commands and SHA-256);replay:
parity/compare.py cbst_trace --store device(the store) andparity/compare.py hypergraph_ids(the container) on every backend;dyng-compat-escher to-dgbturns an ESCHER-GPU trace into.hg+.dgbfiles for M9’s replays.
perf_ab.py run takes $DYNG_SCRATCH/perf.lock itself; under the machine’s convention
flock "$DYNG_SCRATCH/perf.lock" <command> it sees in /proc/locks that its flock(1) ancestor
holds the lock and runs under it (DYNG_PERF_LOCK_HELD=1 or --no-lock say so explicitly). A
lock held by another measurement is waited for at most --lock-timeout seconds. It times only
a parity-preset build (parity-cuda with --backend cuda; --allow-non-parity-build marks
an experiment) and exits non-zero if the deterministic counters differ in any round. The CUDA A/B
runs both sides on --gpu (default 0, the performance GPU). Replays and tests of CUDA code run on
GPU 1 (CUDA_VISIBLE_DEVICES) unless set.
Rules#
A comparison is never loosened to make a port pass; a mismatch is fixed in dynG (never in the original) or, if the original is wrong, documented on the algorithm page as “Paper vs fixed code”.
Export patches are additive only: new files, no change to any tracked file of the original (
build_reference.shchecks it after every build).Performance baselines come only from the unpatched copy.
Results that matter are committed under
results/, not left in logs.