Skip to content

cxxtest baselines fail under msvc 192 (VS2019): floating-point divergence from VS2022 #85

Description

@gagelarsen

Summary

Building xmsmesher for msvc 192 (VS2019) fails the cxxtest suite — 21 of 214 tests — while the same source passes under msvc 194 (VS2022) in CI. The failures are floating-point comparison mismatches against checked-in baseline files, not build or link errors.

Found while putting xmsmesher 6.0.8 onto the VS2019 bridge (aquaveo-vs2019). Every other library in the suite — xmscore, xmsgrid, xmsinterp, xmsextractor — built 14/14 clean; xmsmesher is the only one that is this FP-sensitive.

Evidence

Divergence appears around the 9th significant digit:

ND 27  8.5108203108082   31.7579582765     <- baseline (generated with VS2022 / msvc 194)
ND 27  8.5108203218325   31.75795805983    <- produced by VS2019 / msvc 192

Failing assertions are in:

  • xmsmesher/meshing/MeMultiPolyTo2dm.cpp:333 and :572 — ~18 Files different on line N failures
  • xmsmesher/tutorial/TutMeshing.cpp:284 — 3 failures

Which configurations

The split is exactly along the testing option. Everything that only compiles and links succeeds; only the four configurations that run the suite fail.

result configurations
FAIL (4) Debug-dynamic-testing, Debug-static-testing, Release-dynamic-testing, Release-static-testing
ok (10) both wchar_t variants × Debug/Release × static/dynamic, plus Release-dynamic-pybind for py3.10 and py3.13

So the msvc 192 binaries themselves are fine — it is the baseline comparison that does not hold across compilers.

Why the existing FP workaround does not cover this

build.toml already carries an FP-determinism guard:

# Disable FP contraction (FMA fusion) for consistent floating-point results across
# architectures. GCC on ARM emits fmadd at -O2+ which breaks exact arithmetic
# predicates and produces non-deterministic geometry results.
if (NOT MSVC)
    add_compile_options(-ffp-contract=off)
endif()

It is scoped if (NOT MSVC) because MSVC does not contract by default. That reasoning holds for x86_64-vs-ARM under GCC, but it does not address msvc 192 vs msvc 194 producing different results from the same source — which is what this issue is about.

Current state

xmsmesher 6.0.8 is published to aquaveo-vs2019 with 10 of 14 package ids. The four testing=True variants are absent for msvc 192. Nothing in the XMS dependency DAG consumes xmsmesher's testing package, so this does not block any other library; it means xmsmesher's own test variants cannot be built for VS2019.

aquaveo-stable is unaffected and carries the full msvc 194 / gcc / clang set.

Options

  1. Relax the comparison tolerance in MeMultiPolyTo2dm.cpp and TutMeshing.cpp so the assertions compare with an epsilon rather than exact text. Correct long-term; needs someone who knows the acceptable numerical tolerance for these meshes.
  2. Pin FP behavior for MSVC (/fp:strict, or extending the contraction guard to MSVC) so both compilers agree. Most principled, but it would change VS2022 output and therefore require regenerating baselines anyway.
  3. Accept the gap and keep skipping the testing variants on VS2019 via --filter '{"options": {"testing": false}}'. This is the current state.

Option 3 is what is in place. 1 or 2 wants an owner who knows the meshing numerics.

Note: unrelated tooling bug

xmsconan vs2019 build exited with code 0 despite 4 failed configurations — the summary table reported succeeded 9 / failed 4 but the process return code was 0. A script trusting the exit code would treat the run as clean and publish a partial set silently. Filed separately against xmsconan; noting here because it is how this nearly went unnoticed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions