Browse Source

Remove restrictions from vector utilities

pull/2933/head
James Jackson-South 8 months ago
parent
commit
6b5392bc3d
  1. 18
      src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
  2. 4
      src/ImageSharp/Common/Helpers/Vector128Utilities.cs
  3. 37
      src/ImageSharp/Common/Helpers/Vector256Utilities.cs
  4. 37
      src/ImageSharp/Common/Helpers/Vector512Utilities.cs
  5. 2
      src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs

18
src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs

@ -66,9 +66,9 @@ internal static partial class SimdUtils
ref Span<float> destination,
[ConstantExpected] byte control)
{
if ((Vector512.IsHardwareAccelerated && Vector512_.SupportsShuffleNativeFloat) ||
(Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleNativeFloat) ||
Vector128.IsHardwareAccelerated)
if (Vector512.IsHardwareAccelerated ||
Vector256.IsHardwareAccelerated ||
Vector128.IsHardwareAccelerated)
{
int remainder = 0;
if (Vector512.IsHardwareAccelerated)
@ -112,8 +112,8 @@ internal static partial class SimdUtils
ref Span<byte> destination,
[ConstantExpected] byte control)
{
if ((Vector512.IsHardwareAccelerated && Vector512_.SupportsShuffleNativeByte) ||
(Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleNativeByte) ||
if (Vector512.IsHardwareAccelerated ||
Vector256.IsHardwareAccelerated ||
Vector128.IsHardwareAccelerated)
{
int remainder = 0;
@ -249,7 +249,7 @@ internal static partial class SimdUtils
Span<float> destination,
[ConstantExpected] byte control)
{
if (Vector512.IsHardwareAccelerated && Vector512_.SupportsShuffleNativeFloat)
if (Vector512.IsHardwareAccelerated)
{
ref Vector512<float> sourceBase = ref Unsafe.As<float, Vector512<float>>(ref MemoryMarshal.GetReference(source));
ref Vector512<float> destinationBase = ref Unsafe.As<float, Vector512<float>>(ref MemoryMarshal.GetReference(destination));
@ -277,7 +277,7 @@ internal static partial class SimdUtils
}
}
}
else if (Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleNativeFloat)
else if (Vector256.IsHardwareAccelerated)
{
ref Vector256<float> sourceBase = ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(source));
ref Vector256<float> destinationBase = ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(destination));
@ -341,7 +341,7 @@ internal static partial class SimdUtils
Span<byte> destination,
[ConstantExpected] byte control)
{
if (Vector512.IsHardwareAccelerated && Vector512_.SupportsShuffleNativeByte)
if (Vector512.IsHardwareAccelerated)
{
Span<byte> temp = stackalloc byte[Vector512<byte>.Count];
Shuffle.MMShuffleSpan(ref temp, control);
@ -373,7 +373,7 @@ internal static partial class SimdUtils
}
}
}
else if (Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleNativeByte)
else if (Vector256.IsHardwareAccelerated)
{
Span<byte> temp = stackalloc byte[Vector256<byte>.Count];
Shuffle.MMShuffleSpan(ref temp, control);

4
src/ImageSharp/Common/Helpers/Vector128Utilities.cs

@ -1323,7 +1323,9 @@ internal static class Vector128_
{
// https://stackoverflow.com/questions/11870910/sse-mm-movemask-epi8-equivalent-method-for-arm-neon
Vector128<byte> powers = Vector128.Create(1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128);
Vector128<byte> masked = value & powers;
Vector128<byte> msbMask = Vector128.Create((byte)0x80);
Vector128<byte> normalized = AdvSimd.CompareEqual(value & msbMask, msbMask); // 0xFF or 0x00
Vector128<byte> masked = normalized & powers;
Vector128<ushort> sum8 = AdvSimd.AddPairwiseWidening(masked);
Vector128<uint> sum16 = AdvSimd.AddPairwiseWidening(sum8);

37
src/ImageSharp/Common/Helpers/Vector256Utilities.cs

@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
@ -21,24 +20,6 @@ namespace SixLabors.ImageSharp.Common.Helpers;
internal static class Vector256_
#pragma warning restore SA1649 // File name should match first type name
{
/// <summary>
/// Gets a value indicating whether shuffle byte operations are supported.
/// </summary>
public static bool SupportsShuffleNativeFloat
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Avx.IsSupported;
}
/// <summary>
/// Gets a value indicating whether shuffle byte operations are supported.
/// </summary>
public static bool SupportsShuffleNativeByte
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Avx2.IsSupported;
}
/// <summary>
/// Creates a new vector by selecting values from an input vector using a set of indices.
/// </summary>
@ -47,15 +28,7 @@ internal static class Vector256_
/// <returns>The <see cref="Vector256{Single}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<float> ShuffleNative(Vector256<float> vector, [ConstantExpected] byte control)
{
if (Avx.IsSupported)
{
return Avx.Shuffle(vector, vector, control);
}
ThrowUnreachableException();
return default;
}
=> Avx.Shuffle(vector, vector, control);
/// <summary>
/// Creates a new vector by selecting values from an input vector using a set of indices.</summary>
@ -73,8 +46,9 @@ internal static class Vector256_
return Avx2.Shuffle(vector, indices);
}
ThrowUnreachableException();
return default;
return Vector256.Create(
Vector128_.ShuffleNative(vector.GetLower(), indices.GetLower()),
Vector128_.ShuffleNative(vector.GetUpper(), indices.GetUpper()));
}
/// <summary>
@ -508,7 +482,4 @@ internal static class Vector256_
int hiMask = Vector128_.MoveMask(value.GetUpper());
return loMask | (hiMask << 16);
}
[DoesNotReturn]
private static void ThrowUnreachableException() => throw new UnreachableException();
}

37
src/ImageSharp/Common/Helpers/Vector512Utilities.cs

@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
@ -21,24 +20,6 @@ namespace SixLabors.ImageSharp.Common.Helpers;
internal static class Vector512_
#pragma warning restore SA1649 // File name should match first type name
{
/// <summary>
/// Gets a value indicating whether shuffle float operations are supported.
/// </summary>
public static bool SupportsShuffleNativeFloat
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Avx512F.IsSupported;
}
/// <summary>
/// Gets a value indicating whether shuffle byte operations are supported.
/// </summary>
public static bool SupportsShuffleNativeByte
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Avx512BW.IsSupported;
}
/// <summary>
/// Creates a new vector by selecting values from an input vector using the control.
/// </summary>
@ -47,15 +28,7 @@ internal static class Vector512_
/// <returns>The <see cref="Vector512{Single}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector512<float> ShuffleNative(Vector512<float> vector, [ConstantExpected] byte control)
{
if (Avx512F.IsSupported)
{
return Avx512F.Shuffle(vector, vector, control);
}
ThrowUnreachableException();
return default;
}
=> Avx512F.Shuffle(vector, vector, control);
/// <summary>
/// Creates a new vector by selecting values from an input vector using a set of indices.
@ -73,8 +46,9 @@ internal static class Vector512_
return Avx512BW.Shuffle(vector, indices);
}
ThrowUnreachableException();
return default;
return Vector512.Create(
Vector256_.ShuffleNative(vector.GetLower(), indices.GetLower()),
Vector256_.ShuffleNative(vector.GetUpper(), indices.GetUpper()));
}
/// <summary>
@ -175,7 +149,4 @@ internal static class Vector512_
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector512<T> Clamp<T>(Vector512<T> value, Vector512<T> min, Vector512<T> max)
=> Vector512.Min(Vector512.Max(value, min), max);
[DoesNotReturn]
private static void ThrowUnreachableException() => throw new UnreachableException();
}

2
src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs

@ -12,7 +12,7 @@ internal static class ColorSpaceTransformUtils
{
public static void CollectColorBlueTransforms(Span<uint> bgra, int stride, int tileWidth, int tileHeight, int greenToBlue, int redToBlue, Span<int> histo)
{
if (Vector256_.SupportsShuffleNativeByte && tileWidth >= 16)
if (Vector256.IsHardwareAccelerated && tileWidth >= 16)
{
const int span = 16;
Span<ushort> values = stackalloc ushort[span];

Loading…
Cancel
Save