FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
0400 — Seven regression baselines and one pin differ on MSVC (seabed and TrawlCable runs); skipped on Windows
ID 0400
Class TEST
Severity 2
Status blocked

Models: CableRM, CableBranched, TrawlCable, MooringCable

Found: 2026-10-19, tag pipeline of v3.0.9 (pipeline 1863764, the Windows jobs without visualisation)

Decision needed: whether to replace these baselines with statistic checks (mean and spread over a window; the owner approved that direction for the chaotic bed baselines earlier, but nothing is implemented) or to keep one baseline per platform.

Evidence

In the v3.0.9 tag pipeline the four Windows jobs without visualisation (3714426 msvc_192 Release, 3714427 msvc_194 Release, 3714430 msvc_192 Debug, 3714431 msvc_194 Debug) fail the same six regression tests and one pin (plus the three golden-mesh text compares, fixed separately in 3.0.10). The failing set is identical in all four jobs, Release and Debug, MSVC 192 and 194. The same tests pass on Linux (gcc) with the tight baselines, which were set on the Linux CI binary.

The baselines are compared with RunAndCompareRegressionXmlTiming (RMS per output column). The first two failing outputs of each test, from job 3714426:

Test First failing output RMS Second failing output RMS Tolerance
CableBranched_BedRegression CB/Force1_0 1.388987e-01 CB/Force1_1 4.398129e-03 1e-10
CableRM_SeabedRegression C/ForceA_0 8.470060e+02 C/ForceA_1 1.123163e+02 1e-10
TrawlCable_BedRegression CableS/BottomBridleEndForce_0 3.628985e+02 CableS/BottomBridleEndForce_1 2.203892e+02 1e-10
TrawlCable_EulerRegression CableS/BottomBridleEndForce_0 3.683654e+00 CableS/BottomBridleEndForce_1 7.743588e-01 1e-8
TrawlCable_HeunRegression CableS/BottomBridleEndForce_0 1.407195e-05 CableS/BottomBridleEndForce_1 2.632621e-06 1e-8
TrawlCable_JoinedRegression CableS/BottomBridleEndForce_0 2.416070e+00 CableS/BottomBridleEndForce_1 5.325606e-01 1e-8

Number of failing outputs per test: CableRM_SeabedRegression 136, CableBranched_BedRegression 24, TrawlCable_JoinedRegression 27, TrawlCable_BedRegression 12, TrawlCable_EulerRegression 12, TrawlCable_HeunRegression 7. The CableRM and bed runs differ by large amounts (forces of hundreds of N); the Heun run differs by 1e-5, which is still 1000 times the tolerance.

The seventh test is TrawlCableWakes.SharedSolverDoorPositionsArePinned (tests/TrawlCableWakes_Test.cpp:397-399; it pins the final door position bit for bit, EXPECT_EQ against hex floats). From job 3714426:

Line Quantity Expected (pin, Linux) Got (MSVC)
397 starboard.x() -82.83874 -82.83929
398 starboard.y() 23.45921 23.4587
399 starboard.z() 65.14182 65.14336

The door position differs by 0.5 to 1.5 mm after 1 s of simulated time; the pin expects exact bits, so any rounding difference fails it.

The bed baselines were already known to hold only on the Linux CI binary (1e-10). Contact and sliding runs amplify rounding differences: MSVC and glibc differ in libm (results of exp, pow, tanh in the last bit) and MSVC may contract multiply-add into FMA, so each step starts from slightly different bits and the contact switching decides how far the runs then diverge. These are the likely causes; they have not been measured.

Effect

The ME tag pipeline cannot be green on Windows, so a release has no Windows binaries that run the tests. From 3.0.10 the seven tests are skipped when _MSC_VER is defined (SKIP_ON_MSVC_MARE0400 in tests/TestUtils.h, message naming this issue). They run on Linux with the tight baselines. A model change that moves a result on MSVC only is not caught by these tests.

Possible fix

  1. Replace the baselines with statistic checks: mean and spread (standard deviation) of the key outputs over a time window, with tolerances wide enough for the platform differences but narrow enough to catch a model change. Platform independent, but it needs a ruling on which outputs and what tolerances, and it is weaker than a trace comparison.
  2. Keep one baseline per platform (a second reference file for MSVC next to the Linux one). Keeps the tight check, but doubles the baselines to maintain, and the MSVC ones must be generated on a Windows build.
  3. Find the cause. Build with FMA contraction off on both platforms (-ffp-contract=off for gcc, /fp:precise without contraction for MSVC) and see whether the runs agree. If FMA contraction is the whole cause, the flag makes the baselines portable. If libm is the cause, only 1 or 2 helps.

Test that would prove it

The seven tests run on MSVC (no skip) and pass in the four Windows jobs of the ME tag pipeline, and still pass on Linux. For option 3: the Linux and MSVC runs of CableRM_SeabedRegression agree to 1e-10 with the contraction flags aligned.

Risk

Low for the Linux results (unchanged). The skipped tests leave the MSVC build without a check of the seabed and TrawlCable results. Statistic checks (option 1) could let a small model change through; per-platform baselines (option 2) can go stale on one platform.