Repository navigation
refactor(semantic): never fuse multiply-add in the semantic scores - #168
Merged
Merged
Conversation
The C semantic code never asked for fused multiply-add, but compilers decided for it: Apple clang fused `a * b + c` on arm64, while the Linux release (gcc -std=c11) and the baseline-CPU x86_64 builds did not. The semantic scores therefore differed in the last bit between platforms, which can flip a SEMANTICALLY_RELATED edge whose score sits exactly at the threshold. The Zig port (#166) copied clang's choice through fp.mulAdd, which fuses wherever the CPU has FMA. That kept macOS arm64 unchanged but changed Linux arm64, and the store quantizer (#165) never fused at all. Use one rule everywhere instead: never fuse. Zig does not fuse on its own, so `a * b + c` is written as-is and every platform computes the same scores. fp.zig is removed; its call sites in semantic.zig, rotsq.zig and pass_semantic_edges.zig become plain expressions with the same operand order. Fusing everywhere was not an option: release builds target the baseline x86_64 CPU, which has no FMA instruction, so @mulAdd would become a software fma call in the hot loops. Signed-off-by: ata-sesli <atasesli@protonmail.com>
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.
What does this PR do?
Makes the semantic scores identical on every platform by never fusing
a * b + cinto one fused multiply-add (FMA) instruction.The problem. A fused multiply-add rounds once instead of twice, so its result can differ from a separate multiply and add in the last bit. The C code never chose either way; the compiler did:
-std=c11)The Zig ports then made two different choices.
src/semantic/fp.zig(#166, also used inpass_semantic_edges.zigfrom #167) fuses wherever the CPU has FMA, copying clang. That changed Linux arm64 compared with the C release. The store quantizer (#165) never fuses, which changed macOS arm64.The effect. Scores move by about 1e-6. That matters only where a score sits right at a threshold: a
SEMANTICALLY_RELATEDedge at exactly 0.75, or a dot product of almost exactly zero when vectors are bucketed by sign. In those cases two machines indexing the same repository can disagree on an edge.The change. One rule everywhere: never fuse.
fp.zigis removed. Its call sites insemantic.zig,rotsq.zigandpass_semantic_edges.zigbecome plaina * b + c(orx += a * b), with the same operand order.semantic.zig.Why not always fuse? Release builds target the baseline x86_64 CPU (
-mcpu=baseline), which has no FMA instruction. There,@mulAddbecomes a softwarefmacall inside the semantic hot loops.Behavior change. Compared with the previous release, macOS arm64 and Windows arm64 can differ by one rounding step. In rare cases that changes an edge whose score sits exactly at the threshold. Linux and x86_64 builds compute what the C release computed.
Verification
libcbm_zig.abuilds natively on macOS arm64 (zig build-lib -O ReleaseFast, as inMakefile.cbm).zig fmt --checkpasses on the changed files.scripts/check-build-sources.shpasses.Not run locally: the test suites, the cross-target builds and a cross-platform edge comparison. CI covers the tests and builds.
Checklist
git commit -s)make -f Makefile.cbm test): not run locally; CI runs the suitesmake -f Makefile.cbm lint-ci): not run