Skip to content

Commit

Permalink
Merge pull request #2422 from gfoidl/vector-count-helper
Browse files Browse the repository at this point in the history
Added and used Numerics.Vector{128|256}Count extension
  • Loading branch information
JimBobSquarePants committed Mar 29, 2023
2 parents 4989e14 + 0b140a4 commit bab277c
Show file tree
Hide file tree
Showing 17 changed files with 129 additions and 39 deletions.
90 changes: 90 additions & 0 deletions src/ImageSharp/Common/Helpers/Numerics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -949,4 +949,94 @@ public static int EvenReduceSum(Vector256<int> accumulator)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsOutOfRange(int value, int min, int max)
=> (uint)(value - min) > (uint)(max - min);

/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint VectorCount<TVector>(this Span<byte> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector<TVector>.Count;

/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector128Count<TVector>(this Span<byte> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector128<TVector>.Count;

/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector128Count<TVector>(this ReadOnlySpan<byte> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector128<TVector>.Count;

/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector256Count<TVector>(this Span<byte> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector256<TVector>.Count;

/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector256Count<TVector>(this ReadOnlySpan<byte> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector256<TVector>.Count;

/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint VectorCount<TVector>(this Span<float> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector<TVector>.Count;

/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector128Count<TVector>(this Span<float> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector128<TVector>.Count;

/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector256Count<TVector>(this Span<float> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector256<TVector>.Count;

/// <summary>
/// Gets the count of vectors that safely fit into length.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="length">The given length.</param>
/// <returns>Count of vectors that safely fit into the length.</returns>
public static nuint Vector256Count<TVector>(int length)
where TVector : struct
=> (uint)length / (uint)Vector256<TVector>.Count;
}
4 changes: 2 additions & 2 deletions src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ internal static void ByteToNormalizedFloat(ReadOnlySpan<byte> source, Span<float
{
VerifySpanInput(source, dest, Vector<byte>.Count);

nuint n = (uint)dest.Length / (uint)Vector<byte>.Count;
nuint n = dest.VectorCount<byte>();

ref Vector<byte> sourceBase = ref Unsafe.As<byte, Vector<byte>>(ref MemoryMarshal.GetReference(source));
ref Vector<float> destBase = ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(dest));
Expand Down Expand Up @@ -132,7 +132,7 @@ internal static void NormalizedFloatToByteSaturate(
{
VerifySpanInput(source, dest, Vector<byte>.Count);

nuint n = (uint)dest.Length / (uint)Vector<byte>.Count;
nuint n = dest.VectorCount<byte>();

ref Vector<float> sourceBase =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(source));
Expand Down
20 changes: 10 additions & 10 deletions src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ private static void Shuffle4(
ref Vector256<float> destBase =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(dest));

nint n = (nint)(uint)(dest.Length / Vector256<float>.Count);
nint n = (nint)dest.Vector256Count<float>();
nint m = Numerics.Modulo4(n);
nint u = n - m;

Expand Down Expand Up @@ -392,7 +392,7 @@ private static void Shuffle3(
ref Vector128<byte> destBase =
ref Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(dest));

nuint n = (uint)source.Length / (uint)Vector128<byte>.Count;
nuint n = source.Vector128Count<byte>();

for (nuint i = 0; i < n; i += 3)
{
Expand Down Expand Up @@ -455,7 +455,7 @@ private static void Pad3Shuffle4(
ref Vector128<byte> destBase =
ref Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(dest));

nuint n = (uint)source.Length / (uint)Vector128<byte>.Count;
nuint n = source.Vector128Count<byte>();

for (nuint i = 0, j = 0; i < n; i += 3, j += 4)
{
Expand Down Expand Up @@ -499,7 +499,7 @@ private static void Shuffle4Slice3(
ref Vector128<byte> destBase =
ref Unsafe.As<byte, Vector128<byte>>(ref MemoryMarshal.GetReference(dest));

nuint n = (uint)source.Length / (uint)Vector128<byte>.Count;
nuint n = source.Vector128Count<byte>();

for (nuint i = 0, j = 0; i < n; i += 4, j += 3)
{
Expand Down Expand Up @@ -679,7 +679,7 @@ internal static unsafe void ByteToNormalizedFloat(
{
VerifySpanInput(source, dest, Vector256<byte>.Count);

nuint n = (uint)dest.Length / (uint)Vector256<byte>.Count;
nuint n = dest.Vector256Count<byte>();

ref Vector256<float> destBase =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(dest));
Expand Down Expand Up @@ -712,7 +712,7 @@ internal static unsafe void ByteToNormalizedFloat(
// Sse
VerifySpanInput(source, dest, Vector128<byte>.Count);

nuint n = (uint)dest.Length / (uint)Vector128<byte>.Count;
nuint n = dest.Vector128Count<byte>();

ref Vector128<float> destBase =
ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(dest));
Expand Down Expand Up @@ -811,7 +811,7 @@ internal static void NormalizedFloatToByteSaturate(
{
VerifySpanInput(source, dest, Vector256<byte>.Count);

nuint n = (uint)dest.Length / (uint)Vector256<byte>.Count;
nuint n = dest.Vector256Count<byte>();

ref Vector256<float> sourceBase =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(source));
Expand Down Expand Up @@ -850,7 +850,7 @@ internal static void NormalizedFloatToByteSaturate(
// Sse
VerifySpanInput(source, dest, Vector128<byte>.Count);

nuint n = (uint)dest.Length / (uint)Vector128<byte>.Count;
nuint n = dest.Vector128Count<byte>();

ref Vector128<float> sourceBase =
ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(source));
Expand Down Expand Up @@ -893,7 +893,7 @@ internal static void PackFromRgbPlanesAvx2Reduce(
ref Vector256<byte> bBase = ref Unsafe.As<byte, Vector256<byte>>(ref MemoryMarshal.GetReference(blueChannel));
ref byte dBase = ref Unsafe.As<Rgb24, byte>(ref MemoryMarshal.GetReference(destination));

nuint count = (uint)redChannel.Length / (uint)Vector256<byte>.Count;
nuint count = redChannel.Vector256Count<byte>();

ref byte control1Bytes = ref MemoryMarshal.GetReference(PermuteMaskEvenOdd8x32);
Vector256<uint> control1 = Unsafe.As<byte, Vector256<uint>>(ref control1Bytes);
Expand Down Expand Up @@ -965,7 +965,7 @@ internal static void PackFromRgbPlanesAvx2Reduce(
ref Vector256<byte> bBase = ref Unsafe.As<byte, Vector256<byte>>(ref MemoryMarshal.GetReference(blueChannel));
ref Vector256<byte> dBase = ref Unsafe.As<Rgba32, Vector256<byte>>(ref MemoryMarshal.GetReference(destination));

nuint count = (uint)redChannel.Length / (uint)Vector256<byte>.Count;
nuint count = redChannel.Vector256Count<byte>();
ref byte control1Bytes = ref MemoryMarshal.GetReference(PermuteMaskEvenOdd8x32);
Vector256<uint> control1 = Unsafe.As<byte, Vector256<uint>>(ref control1Bytes);
var a = Vector256.Create((byte)255);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public override void ConvertToRgbInplace(in ComponentValues values)
// Used for the color conversion
var scale = Vector256.Create(1 / (this.MaximumValue * this.MaximumValue));

nuint n = (uint)values.Component0.Length / (uint)Vector256<float>.Count;
nuint n = values.Component0.Vector256Count<float>();
for (nuint i = 0; i < n; i++)
{
ref Vector256<float> c = ref Unsafe.Add(ref c0Base, i);
Expand Down Expand Up @@ -71,7 +71,7 @@ public static void ConvertFromRgb(in ComponentValues values, float maxValue, Spa

var scale = Vector256.Create(maxValue);

nuint n = (uint)values.Component0.Length / (uint)Vector256<float>.Count;
nuint n = values.Component0.Vector256Count<float>();
for (nuint i = 0; i < n; i++)
{
Vector256<float> ctmp = Avx.Subtract(scale, Unsafe.Add(ref srcR, i));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected override void ConvertToRgbInplaceVectorized(in ComponentValues values)

var scale = new Vector<float>(1 / (this.MaximumValue * this.MaximumValue));

nuint n = (uint)values.Component0.Length / (uint)Vector<float>.Count;
nuint n = values.Component0.VectorCount<float>();
for (nuint i = 0; i < n; i++)
{
ref Vector<float> c = ref Unsafe.Add(ref cBase, i);
Expand Down Expand Up @@ -78,7 +78,7 @@ public static void ConvertFromRgbInplaceVectorized(in ComponentValues values, fl
// Used for the color conversion
var scale = new Vector<float>(maxValue);

nuint n = (uint)values.Component0.Length / (uint)Vector<float>.Count;
nuint n = values.Component0.VectorCount<float>();
for (nuint i = 0; i < n; i++)
{
Vector<float> ctmp = scale - Unsafe.Add(ref srcR, i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public override void ConvertToRgbInplace(in ComponentValues values)
// Used for the color conversion
var scale = Vector128.Create(1 / this.MaximumValue);

nuint n = (uint)values.Component0.Length / (uint)Vector128<float>.Count;
nuint n = values.Component0.Vector128Count<float>();
for (nuint i = 0; i < n; i++)
{
ref Vector128<float> c0 = ref Unsafe.Add(ref c0Base, i);
Expand All @@ -53,7 +53,7 @@ public override void ConvertFromRgb(in ComponentValues values, Span<float> rLane
var f0587 = Vector128.Create(0.587f);
var f0114 = Vector128.Create(0.114f);

nuint n = (uint)values.Component0.Length / (uint)Vector128<float>.Count;
nuint n = values.Component0.Vector128Count<float>();
for (nuint i = 0; i < n; i++)
{
ref Vector128<float> r = ref Unsafe.Add(ref srcRed, i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public override void ConvertToRgbInplace(in ComponentValues values)
// Used for the color conversion
var scale = Vector256.Create(1 / this.MaximumValue);

nuint n = (uint)values.Component0.Length / (uint)Vector256<float>.Count;
nuint n = values.Component0.Vector256Count<float>();
for (nuint i = 0; i < n; i++)
{
ref Vector256<float> c0 = ref Unsafe.Add(ref c0Base, i);
Expand All @@ -53,7 +53,7 @@ public override void ConvertFromRgb(in ComponentValues values, Span<float> rLane
var f0587 = Vector256.Create(0.587f);
var f0114 = Vector256.Create(0.114f);

nuint n = (uint)values.Component0.Length / (uint)Vector256<float>.Count;
nuint n = values.Component0.Vector256Count<float>();
for (nuint i = 0; i < n; i++)
{
ref Vector256<float> r = ref Unsafe.Add(ref srcRed, i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ protected override void ConvertToRgbInplaceVectorized(in ComponentValues values)

var scale = new Vector<float>(1 / this.MaximumValue);

nuint n = (uint)values.Component0.Length / (uint)Vector<float>.Count;
nuint n = values.Component0.VectorCount<float>();
for (nuint i = 0; i < n; i++)
{
ref Vector<float> c0 = ref Unsafe.Add(ref cBase, i);
Expand Down Expand Up @@ -53,7 +53,7 @@ protected override void ConvertFromRgbVectorized(in ComponentValues values, Span
var gMult = new Vector<float>(0.587f);
var bMult = new Vector<float>(0.114f);

nuint n = (uint)values.Component0.Length / (uint)Vector<float>.Count;
nuint n = values.Component0.VectorCount<float>();
for (nuint i = 0; i < n; i++)
{
Vector<float> r = Unsafe.Add(ref srcR, i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public override void ConvertToRgbInplace(in ComponentValues values)

// Used for the color conversion
var scale = Vector128.Create(1 / this.MaximumValue);
nuint n = (uint)values.Component0.Length / (uint)Vector128<float>.Count;
nuint n = values.Component0.Vector128Count<float>();
for (nuint i = 0; i < n; i++)
{
ref Vector128<float> r = ref Unsafe.Add(ref rBase, i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public override void ConvertToRgbInplace(in ComponentValues values)

// Used for the color conversion
var scale = Vector256.Create(1 / this.MaximumValue);
nuint n = (uint)values.Component0.Length / (uint)Vector256<float>.Count;
nuint n = values.Component0.Vector256Count<float>();
for (nuint i = 0; i < n; i++)
{
ref Vector256<float> r = ref Unsafe.Add(ref rBase, i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ protected override void ConvertToRgbInplaceVectorized(in ComponentValues values)

var scale = new Vector<float>(1 / this.MaximumValue);

nuint n = (uint)values.Component0.Length / (uint)Vector<float>.Count;
nuint n = values.Component0.VectorCount<float>();
for (nuint i = 0; i < n; i++)
{
ref Vector<float> r = ref Unsafe.Add(ref rBase, i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public override void ConvertToRgbInplace(in ComponentValues values)
var bCbMult = Vector256.Create(YCbCrScalar.BCbMult);

// Walking 8 elements at one step:
nuint n = (uint)values.Component0.Length / (uint)Vector256<float>.Count;
nuint n = values.Component0.Vector256Count<float>();
for (nuint i = 0; i < n; i++)
{
// y = yVals[i];
Expand Down Expand Up @@ -98,7 +98,7 @@ public override void ConvertFromRgb(in ComponentValues values, Span<float> rLane
var fn0081312F = Vector256.Create(-0.081312F);
var f05 = Vector256.Create(0.5f);

nuint n = (uint)values.Component0.Length / (uint)Vector256<float>.Count;
nuint n = values.Component0.Vector256Count<float>();
for (nuint i = 0; i < n; i++)
{
Vector256<float> r = Unsafe.Add(ref srcR, i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ protected override void ConvertToRgbInplaceVectorized(in ComponentValues values)
var gCrMult = new Vector<float>(-YCbCrScalar.GCrMult);
var bCbMult = new Vector<float>(YCbCrScalar.BCbMult);

nuint n = (uint)values.Component0.Length / (uint)Vector<float>.Count;
nuint n = values.Component0.VectorCount<float>();
for (nuint i = 0; i < n; i++)
{
// y = yVals[i];
Expand Down Expand Up @@ -103,7 +103,7 @@ protected override void ConvertFromRgbVectorized(in ComponentValues values, Span
var gCrMult = new Vector<float>(0.418688f);
var bCrMult = new Vector<float>(0.081312f);

nuint n = (uint)values.Component0.Length / (uint)Vector<float>.Count;
nuint n = values.Component0.VectorCount<float>();
for (nuint i = 0; i < n; i++)
{
Vector<float> r = Unsafe.Add(ref srcR, i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public override void ConvertToRgbInplace(in ComponentValues values)
var bCbMult = Vector256.Create(YCbCrScalar.BCbMult);

// Walking 8 elements at one step:
nuint n = (uint)values.Component0.Length / (uint)Vector256<float>.Count;
nuint n = values.Component0.Vector256Count<float>();
for (nuint i = 0; i < n; i++)
{
// y = yVals[i];
Expand Down Expand Up @@ -109,7 +109,7 @@ public override void ConvertFromRgb(in ComponentValues values, Span<float> rLane
var fn0081312F = Vector256.Create(-0.081312F);
var f05 = Vector256.Create(0.5f);

nuint n = (uint)values.Component0.Length / (uint)Vector256<float>.Count;
nuint n = values.Component0.Vector256Count<float>();
for (nuint i = 0; i < n; i++)
{
Vector256<float> r = Avx.Subtract(maxSampleValue, Unsafe.Add(ref srcR, i));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ protected override void ConvertToRgbInplaceVectorized(in ComponentValues values)
var gCrMult = new Vector<float>(-YCbCrScalar.GCrMult);
var bCbMult = new Vector<float>(YCbCrScalar.BCbMult);

nuint n = (uint)values.Component0.Length / (uint)Vector<float>.Count;
nuint n = values.Component0.VectorCount<float>();
for (nuint i = 0; i < n; i++)
{
// y = yVals[i];
Expand Down Expand Up @@ -107,7 +107,7 @@ protected override void ConvertFromRgbVectorized(in ComponentValues values, Span
var gCrMult = new Vector<float>(0.418688f);
var bCrMult = new Vector<float>(0.081312f);

nuint n = (uint)values.Component0.Length / (uint)Vector<float>.Count;
nuint n = values.Component0.VectorCount<float>();
for (nuint i = 0; i < n; i++)
{
Vector<float> r = maxSampleValue - Unsafe.Add(ref srcR, i);
Expand Down
Loading

0 comments on commit bab277c

Please sign in to comment.