Repository navigation
Closed
Labels
upstream-issueIssue depends on upstream dependency fix.Issue depends on upstream dependency fix.
Description
Prerequisites
- I have written a descriptive issue title
- I have verified that I am running the latest version of ImageSharp
- I have verified if the problem exist in both
DEBUGandRELEASEmode - I have searched open and closed issues to ensure it has not already been reported
ImageSharp version
Current main branch
Other ImageSharp packages and versions
none
Environment (Operating system, version and so on)
Windows 10
.NET Framework version
- 7.0.100-preview.4.22252.9
- 7.0.100-preview.6.22352.1
- 7.0.100-preview.7.22377.5
- 7.0.100-rc.1.22431.12
Description
The following tests fail on .NET 7.0 Windows only. Introduced in 7.0.100-preview.4.22252.9:
Skew_IsNotBoundToSinglePixelType<Bgra32>(provider: TestPattern100x50[Bgra32], x: 20, y: 10)Skew_IsNotBoundToSinglePixelType<Bgra32>(provider: TestPattern100x50[Bgra32], x: -20, y: -10)
The issue seems to be only occurring in Release mode. Also it seems somehow related to the PixelFormat Bgra32
Environment Info
OS=Windows 10.0.20348
Intel Xeon Platinum 8272CL CPU 2.60GHz, 1 CPU, 2 logical and 2 physical cores
.NET SDK=7.0.100-preview.6.22352.1
[Host] : .NET 7.0.0 (7.0.22.32404), X64 RyuJIT
Error Message:
System.PlatformNotSupportedException : Operation is not supported on this platform.
Stack Trace:
at System.Runtime.Intrinsics.Vector256.Create(Single value)
at SixLabors.ImageSharp.Formats.Jpeg.Components.FastFloatingPointDCT.<IDCT8x8_Avx>g__IDCT8x8_1D_Avx|16_0(Block8x8F& block) in /_/src/ImageSharp/Formats/Jpeg/Components/FastFloatingPointDCT.Intrinsic.cs:line 141
at SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.JpegComponentPostProcessor.CopyBlocksToColorBuffer(Int32 spectralStep) in /_/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs:line 70
Environment Info
OS=macOS Big Sur 11.6.7 (20G630) [Darwin 20.6.0]
Intel Xeon CPU E5-1650 v2 3.50GHz (Max: 3.34GHz), 1 CPU, 3 logical and 3 physical cores
.NET SDK=7.0.100-preview.6.22352.1
[Host] : .NET 7.0.0 (7.0.22.32404), X64 RyuJIT
Steps to Reproduce
Run the tests with .NET 7.0 in Release mode.
Images
No response
Metadata
Metadata
Assignees
Labels
upstream-issueIssue depends on upstream dependency fix.Issue depends on upstream dependency fix.
Activity
JimBobSquarePants commentedon May 12, 2022
Do we have the output images? Are they badly off? If so that would likely indicate a JIT error which we can report upstream.
brianpopow commentedon May 12, 2022
Visually, I cant tell the difference, but the report says 30% of the pixels are different.
Expected:

Actual:

I could not pinpoint whats going wrong, since it only happens on Release mode.
To report an issue upstream, we need a smaller reproduction.
JimBobSquarePants commentedon May 13, 2022
The difference is that the RGB components in the actual output for transparent areas are
255,255,255vs0,0,0That it fails for skew and not rotate is confusing as the code differs only on the transform (though that might make it possible to identify a cause).
JimBobSquarePants commentedon May 13, 2022
I cannot replicate this locally. 😔
I had a look at the latest preview release notes and it would take a smarter person than I to narrow down a potential cause without replication.
dotnet/core#7378 (comment)
brianpopow commentedon May 13, 2022
I can replicate it locally, but it seems not to happen always (but very often).
JimBobSquarePants commentedon May 13, 2022
Intermittent! Whoa that’s weird!
brianpopow commentedon May 14, 2022
To add another weird observation to the list: When executing the test via visual studio they always pass. Only executing the tests via command line fails occasionally.
JimBobSquarePants commentedon May 26, 2022
I think it's got something to do with the way we unpremultiply
Vector4instances inNumericswhere theWvalue is0.We actually get 1 of two possible values from both the scalar and simd versions.
If the input
XYZvalues are0then you get<NaN, NaN, NaN, 0>If the values are greater than
0then you get<∞, ∞, ∞, 0>Now what I think is happening is that when we are converting the values to bytes on some chipsets
NaNis somehow being converted into255. What the exact cause (and why it doesn't seem to affect other tests) I do not know yet.brianpopow commentedon May 27, 2022
Maybe handling of NaN/Infinite has changed in .Net7.0? It's still weird that this does not always happens.
edit: the only thing I could find NaN related changed in .Net7.0 seems to be the
Equalmethod: https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/7.0/equals-nanI cant see, how this could affect the Skew Processor, though.
JimBobSquarePants commentedon Jul 14, 2022
We need to add a bunch of diagnostic information to the output when something fails. I'm going to write some code in our tests to do this.
JimBobSquarePants commentedon Jul 16, 2022
@brianpopow I managed to capture the environmental values for the Windows failure.
brianpopow commentedon Jul 16, 2022
The spec of this processor says it has AVX and AVX2, so this seems a different issue then the one reported in #2173.
I still believe it has something to do with how NaN is handled, but it baffles me that this is only happening occasionally.
JimBobSquarePants commentedon Jul 16, 2022
Yep. Definitely different.
What I don't understand is why
Bgra32only? I couldn't find anything in our pipeline that would make conversion fromVector4different. We just shuffle the values first.11 remaining items
tannergooding commentedon Sep 15, 2022
Ok, so I could reliably repro on RC1, but I cannot repro on RC2 (nightly build
7.0.100-rc.2.22464.26).There were ~161 commits between these two: dotnet/runtime@release/7.0-rc1...release/7.0-rc2
Of those commits, the most likely to impact this would have been:
Both of these should only have impacted
Vector3and only CG2/R2R (Crossgen or Ready To Run) scenarios. I'd expect most of the hardware being run against was SSE4.1 or later, but its possible that there is some specific edge case or dependence on some BCL method (which would be cg2/r2r) that was causing this instead.It would be great if someone else could validate that it is fixed as well, and if so I can dig a little bit deeper to finalize the root cause.
-- Noting that the latest .NET 7 RC2 nightly build may also require the 6.0.10 SDK which I'm not sure where to get atm. I ended up changing the
TargetFrameworksunderSIXLABORS_TESTING_PREVIEWto only benet7.0to work around this.tannergooding commentedon Sep 15, 2022
Hmmm, maybe I spoke too soon.
I'm still seeing the following in a clean build, but it won't repro after having been hit once:
tannergooding commentedon Sep 15, 2022
I've root caused the bug. There looks to be a bug with
maxpsandminps.This is the disassembly for
Bgra32.FromVector4in .NET 6:This is the codegen for the same method in .NET 7:
You'll note that these are basically identical (you can ignore the
GETSHARED_NONGCSTATIC_BASEdifference) except .NET 6 does (simplified):But .NET 7 is doing (simplified):
This might not seem like much, but it has big impact for
NaNbecausemaxps/minpsreturn the right hand side if either operand isNaN. This means .NET 6 propagates up0while .NET 7 propagates upNaN.I believe this is non-deterministic because it somewhat depends on TieredCompilation and when the method becomes optimized. It more reliably reproduces if
FromVector4is marked "no-inlining" and bothFromVector4/Packare markedAggressiveOptimization.Going to see if I can figure out why the JIT is deciding to swap operands here and will try to get a fix up. In the interim, the simple workaround here should be to change
Pack(ref Vector4)to justPack(Vector4). This should be "better" when the method is inlined (and its being aggressively inlined) but also even when not inlined for non-Windows platforms.Adding a regression test for SixLabors/ImageSharp#2117
brianpopow commentedon Sep 15, 2022
@tannergooding: very happy to see that you found the root cause of this. Thanks a lot for working on this issue and providing a fix!
edit:
I will make a PR for that.
Fix for issue #2117
Merge pull request #2230 from SixLabors/bp/FixIssue2117
Ensure Max/Min for floating-point on x86/x64 are not handled as commu…
Adding a regression test for SixLabors/ImageSharp#2117
Ensure Max/Min for floating-point on x86/x64 are not handled as commu…
[release/7.0-rc2] Ensure Max/Min for floating-point on x86/x64 are no…
brianpopow commentedon Sep 22, 2022
closing this now with #2230 merged
[release/6.0] Ensure Max/Min for floating-point on x86/x64 are not ha…