Page MenuHome

Fix tests when building with GCC and march=native
ClosedPublic

Authored by Sebastian Parborg (zeddb) on Sep 29 2020, 12:41 PM.

Details

Summary

When building with more aggressive optimization flags, GCC will add FMA (Fused Multiply Add) instructions that will slightly alter the floating point operation results.

This causes some tests to fail in blender.

In clang and the intel compiler ffp-contract is set to off per default it seems from my research.
(They do not have the exact same setting, but the default seems to match the off behavior)

Diff Detail

Event Timeline

Sebastian Parborg (zeddb) requested review of this revision.Sep 29 2020, 12:41 PM
Sebastian Parborg (zeddb) created this revision.

D8968 also needs to be merged for the tests to pass.
(As it will cause segfaults because of Eigen misalignment)

To me this mainly boils down to a policy: do we really want to attempt to have "pixel-perfect" results no matter which optimization flags are used?

If we really want that, it is something way more involved: we have dependencies which are to be compiled, we have linux distros which are packaging libraries at different version than what we use in official builds. There are so many things which we can not control.

What is it what we are gaining by attempting to support -march=native by disabling certain optimizations? What issues are fixed with this? Can we make it so developers do not use heave optimization flags?

build_files/cmake/platform/platform_unix.cmake
606

This is nice to know defaults, but would also be very nice to know why we need to have ffp-contract=off. Aka: add information that FMA is disabled to be able to run regression tests which might fail due to floating point issues.

Brecht Van Lommel (brecht) requested changes to this revision.Oct 1 2020, 3:16 PM

Adding it to the global compiler flags here may disable FMA in the Cycles kernel with optimized compile flags (and potentially other code), where we do actually want to keep it enabled.

Cycles optimization flags will be added after the PLATFORM_CFLAGS, so if the order -ffp-contract=off -match=native still enables FMA it's fine. Can you check if that is the case?

What is it what we are gaining by attempting to support -march=native by disabling certain optimizations? What issues are fixed with this? Can we make it so developers do not use heave optimization flags?

If enabling this flag yields measurable performance improvements, and studios can get predictable results with just this fix, then I guess we might as well support it.

Making sure no one compiles Blender with additional optimization flags would be a more disruptive change I think.

This revision now requires changes to proceed.Oct 1 2020, 3:16 PM

Adding it to the global compiler flags here may disable FMA in the Cycles kernel with optimized compile flags (and potentially other code), where we do actually want to keep it enabled.

Cycles optimization flags will be added after the PLATFORM_CFLAGS, so if the order -ffp-contract=off -match=native still enables FMA it's fine. Can you check if that is the case?

The order doesn't seem to matter sadly. How should we proceed?

Just for reference these are the tests that are failing with FMA:

728 - polyfill2d.IssueT67109_axis_align_co_linear_b (Failed)
1005 - bmesh_bevel (Failed)
1009 - modifiers (Failed)
1010 - physics_cloth (Failed)
1011 - physics_softbody (Failed)
1051 - evaluate_fcurve.InterpolationBezier (Failed)
1054 - evaluate_fcurve.ExtrapolationBezierKeys (Failed)

The fcurve tests will pass if we simply up the deviation epsilon to 1e-6.

For the others, except polyfill, the result is simply different (but correct) because of the small floating point differences propagating.
So just increasing the epsilon here will not work.

For polyfill, the FMA optimization actually triggers a corner case that the test is looking for.
So the issue it tests for has actually not been fixed just moved around a bit so that it normally doesn't trigger.

I'm not sure about the best solution then, this is getting complicated.

I would check if -march=native and WITH_GTESTS is enabled, and if so print a CMake warning about that being unsupported for tests.

Perhaps we can use the remove_cc_flag macro and simply do remove_cc_flag("-ffp-contract=off") for cycles?

@Brecht Van Lommel (brecht) so how are we going to do this? Are we going to do the remove_cc_flag route?
To me it does makes sense to have the contract=off flag for GCC as it is the default with both clang and the intel compiler it seems (I don't know if it is the same with windows VS compiler)

remove_cc_flag adds a bit of a hidden dependency, but it seems like a reasonable solution here, I can't immediately think of something better.

Sebastian Parborg (zeddb) marked an inline comment as done.

Updated to remove the flag from cycles.

This revision is now accepted and ready to land.Jan 14 2021, 11:30 AM