-
Notifications
You must be signed in to change notification settings - Fork 18k
x/exp/shiny/iconvg: Encoder.SetEllipticalGradient floating point math diverges on ARM64 due to FMA #43219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Same error on linux/arm64 (which doesn't seem to run x/exp tests on the dashboard). Without looking into the detail, my guess is that it has something to do with how floating points are handled on different architectures. I'll look into it. |
With some manual decoding, it in the end boils down to this line (https://go.googlesource.com/exp/+/refs/heads/master/shiny/iconvg/encode.go#419)
On AMD64 it results in
On ARM64,
which leads to different encoding. On ARM64, it generates
with a fused multiply-sub instruction. If we add explicit rounding to prevent fused operations,
then it passes on ARM64. Without the explicit rounding, I think it is allowed by the spec for the compiler to generate fused instructions, which will result in slightly different values. So, maybe the test shouldn't test exact values for floating points, or, if it really wants to, add the explicit rounding. |
Thanks for investigating Cherry. The test expects byte-identical encoding, which we now see isn't going to be the case across architectures. Package
I understand that should imply that it's not a goal for iconvg to try to guarantee byte-exact encoding across architectures, and so the test should be fixed. Please let me know if you prefer we take the other path and do try to make encoding deterministic. CC @nigeltao. |
Decoding (from IconVG to pixels) is not expected to be byte-exact (or RGBA-exact), as there are multiple vector rasterization algorithms of varying speed-quality trade-offs. However, when encoding (to IconVG), I would prefer that e.g. a "convert SVG to IconVG" tool had identical output for identical SVG input, regardless of the GOARCH. I would prefer an explicit
together with a comment similar to https://github.com/golang/image/blob/35266b937fa69456d24ed72a04d75eb6857f7d52/vector/raster_floating.go#L58-L68 I'm not confident in making the CL myself, since I don't have easy access to an ARM64 system right now to make sure that all the broken tests would be fixed, but I'm happy to review a CL. |
@nigeltao Sounds good, thanks for feedback. I’ll send a CL that documents that goal and fixes the implementation accordingly. |
That said, I do want to ask, how much confidence can we have in our ability to achieve and maintain this goal in the general case (that is, for all specification-compliant Go implementations, including compilers other than Considering the room the Go specification leaves to implementation (e.g., "In all non-constant conversions involving floating-point or complex values, if the result type cannot represent the value the conversion succeeds but the result value is implementation-dependent.") and various articles like https://randomascii.wordpress.com/2013/07/16/floating-point-determinism/, https://gafferongames.com/post/floating_point_determinism/, I haven't been able to convince myself yet that floating-point determinism can be achieved reliably in a forward-compatible way. I think there's no harm to try it for now, and reconsider in the future if we encounter sufficient evidence that shows it's not sustainable to guarantee IconVG's deterministic-encoding property (due to it involving floating-point computations). But I wanted to ask in case you have more thoughts on this topic. |
Change https://golang.org/cl/279294 mentions this issue: |
I'll defer to @cherrymui re Go floating-point determinism and FMA, as I think it's more of a Go compiler question than an x/exp/shiny or x/image/vector question. I agree to try it for now and reconsider if it's not working. |
2020-12-15T15:35:30-b5a6e24/darwin-arm64-11_0-toothrot
CC @golang/release @nigeltao @cherrymui
The text was updated successfully, but these errors were encountered: