Browse Source

Implement remaining SIMD utils in JXL

pull/3153/head
winscripter 3 weeks ago
parent
commit
e81085cc83
  1. 36
      src/ImageSharp/Formats/Jxl/Processing/JxlSimdUtils.cs

36
src/ImageSharp/Formats/Jxl/Processing/JxlSimdUtils.cs

@ -2,6 +2,7 @@
// Licensed under the Six Labors Split License.
using System.Numerics;
using System.Numerics.Tensors;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@ -14,6 +15,8 @@ namespace SixLabors.ImageSharp.Formats.Jxl.Processing;
/// </summary>
internal static partial class JxlSimdUtils
{
public static int MaxVectorSize => Vector<float>.Count * sizeof(float);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<T> ConcatLowerLower<T>(Vector256<T> a, Vector256<T> b)
where T : unmanaged => Vector256.Create(a.GetLower(), b.GetLower());
@ -505,6 +508,39 @@ internal static partial class JxlSimdUtils
Vector<float> exponent)
=> FastPow2f(Vector.Log2(@base) * exponent);
public static uint MaxValue(Span<uint> data)
{
int lanes = Vector<uint>.Count;
int lastFull = lanes * (data.Length / lanes);
Vector<uint> max = Vector<uint>.Zero;
ref uint dataRef = ref MemoryMarshal.GetReference(data);
for (int i = 0; i < lastFull; i += lanes)
{
max = Vector.Max(max, Vector.LoadUnsafe(ref Unsafe.Add(ref dataRef, i)));
}
if (lastFull < data.Length)
{
Vector<uint> stop = Vector.Create((uint)data.Length);
Vector<uint> fence = Iota((uint)lastFull);
Vector<uint> take = Vector.LessThan(fence, stop);
max = Vector.Max(
max,
Vector.ConditionalSelect(
take,
Vector.LoadUnsafe(ref Unsafe.Add(ref dataRef, lastFull)),
Vector<uint>.Zero));
}
// The following part is to find the largest number in
// the vector.
Span<uint> copy = stackalloc uint[Vector<uint>.Count];
max.CopyTo(copy);
return TensorPrimitives.Max<uint>(copy);
}
/// <summary>
/// Incrementing values to compute the Iota function.
/// </summary>

Loading…
Cancel
Save