Skip to content

Compare every variant of a multi-variant source, deterministically - #39

Open
anakanemison wants to merge 1 commit into
mschaller/u03-target-map-renames-one-placefrom
mschaller/u04-deterministic-variants
Open

anakanemison wants to merge 1 commit into
mschaller/u03-target-map-renames-one-placefrom
mschaller/u04-deterministic-variants

Conversation

@anakanemison

Copy link
Copy Markdown

Part 4 of 23 of a stacked series (tracking issue: #35). Based on U03-target-map-renames-one-place, the previous part: review and merge that first.

Kind: fix. Lab proposal: P14.

What the migration runs showed

The verdict on qgis depended on PYTHONHASHSEED when a source compiles in several variants. The fixed differ gives one verdict under three seeds (run 089).

The change

_union_tus pooled library TUs into one source-keyed map with
dict.setdefault while iterating a set of target names. When one source is
compiled into several libraries with different flags (a full and a lite
build of the same file, a hardened variant), only one variant per side was
compared, and which one depended on set iteration order, that is, on
PYTHONHASHSEED. The verdict was not reproducible.

Measured in any2bazel-lab: the same MySQL Server models gave 4,715 to 4,817
errors over 10 hash seeds, a different error set each time, and the final
models of a Blender migration converged under 2 of 8 seeds. Projects
without multi-variant sources were unaffected (50 recorded verdicts
identical under 20 seeds).

Pooling now keeps every distinct variant per source, visiting targets in
sorted order. Each CMake variant is compared with its best-matching Bazel
variant: fewest errors, then warnings, then the smallest symmetric
difference of the two TUs' define, flag and include sets, then a stable
text order. Every CMake variant must be matched by some Bazel variant and
nothing is suppressed; an extra Bazel-only variant is tolerated, like an
extra Bazel flag. The distance term keeps a tie from choosing a variant
that only adds flags (-w, -Wno-error=...) over an exact one. A source with
one variant per side takes exactly the old path, and on every
single-variant verdict the lab has recorded, the result is unchanged.
Executables and the opt-in test union use the same pairing, and the Java
source union is visited in sorted order too.

One consequence for source_map users: a token that collapses several CMake
TUs (an AUTOMOC bundle, say) now yields one comparison, and so possibly one
discrepancy, per distinct CMake TU, so the worklist can grow. The
source_map comment in config.py says so.

In the lab's later QGIS run with this change, the differ gave the same
verdict under three seeds.

Testing

pytest tests/ at this commit: 144 passed (130 on main).

🤖 Generated with Claude Code

_union_tus pooled library TUs into one source-keyed map with
dict.setdefault while iterating a set of target names. When one source is
compiled into several libraries with different flags (a full and a lite
build of the same file, a hardened variant), only one variant per side was
compared, and which one depended on set iteration order, that is, on
PYTHONHASHSEED. The verdict was not reproducible.

Measured in any2bazel-lab: the same MySQL Server models gave 4,715 to 4,817
errors over 10 hash seeds, a different error set each time, and the final
models of a Blender migration converged under 2 of 8 seeds. Projects
without multi-variant sources were unaffected (50 recorded verdicts
identical under 20 seeds).

Pooling now keeps every distinct variant per source, visiting targets in
sorted order. Each CMake variant is compared with its best-matching Bazel
variant: fewest errors, then warnings, then the smallest symmetric
difference of the two TUs' define, flag and include sets, then a stable
text order. Every CMake variant must be matched by some Bazel variant and
nothing is suppressed; an extra Bazel-only variant is tolerated, like an
extra Bazel flag. The distance term keeps a tie from choosing a variant
that only adds flags (-w, -Wno-error=...) over an exact one. A source with
one variant per side takes exactly the old path, and on every
single-variant verdict the lab has recorded, the result is unchanged.
Executables and the opt-in test union use the same pairing, and the Java
source union is visited in sorted order too.

One consequence for source_map users: a token that collapses several CMake
TUs (an AUTOMOC bundle, say) now yields one comparison, and so possibly one
discrepancy, per distinct CMake TU, so the worklist can grow. The
source_map comment in config.py says so.

In the lab's later QGIS run with this change, the differ gave the same
verdict under three seeds.

Lab-Proposal: P14
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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