Skip to content
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

[API Proposal]: Vector128/256 AddSaturate/RemoveSaturate #82559

Open
EgorBo opened this issue Feb 23, 2023 · 4 comments
Open

[API Proposal]: Vector128/256 AddSaturate/RemoveSaturate #82559

EgorBo opened this issue Feb 23, 2023 · 4 comments
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.Intrinsics help wanted [up-for-grabs] Good issue for external contributors
Milestone

Comments

@EgorBo
Copy link
Member

EgorBo commented Feb 23, 2023

Background and motivation

I hit lack of these crossplatform helpers when I was doing "parse hex" work in #82521 - ended up with local functions. These APIs seem to present in SSE/AVX and AdvSimd and can be easily exposed as cross-platform helpers. Some places in BCL might benefit from this too, e.g.

if (AdvSimd.IsSupported)
{
charIsThreeByteUtf8Encoded = AdvSimd.AddSaturate(utf16Data, vector7800);
mask = GetNonAsciiBytes(AdvSimd.Or(charIsNonAscii, charIsThreeByteUtf8Encoded).AsByte(), bitMask128);
}
else
{
charIsThreeByteUtf8Encoded = Sse2.AddSaturate(utf16Data, vector7800);
mask = (uint)Sse2.MoveMask(Sse2.Or(charIsNonAscii, charIsThreeByteUtf8Encoded).AsByte());
}

API Proposal

namespace System.Numerics;

public static class Vector
{
+     public static Vector<T> AddSaturate<T>     (Vector<T> left, Vector<T> right) where T : struct;
+     public static Vector<T> SubtractSaturate<T>(Vector<T> left, Vector<T> right) where T : struct;
}

namespace System.Runtime.Intrinsics;

public static class Vector64
{
+     public static Vector64<T> AddSaturate<T>     (Vector64<T> left, Vector64<T> right) where T : struct;
+     public static Vector64<T> SubtractSaturate<T>(Vector64<T> left, Vector64<T> right) where T : struct;
}

public static class Vector128
{
+     public static Vector128<T> AddSaturate<T>     (Vector128<T> left, Vector128<T> right) where T : struct;
+     public static Vector128<T> SubtractSaturate<T>(Vector128<T> left, Vector128<T> right) where T : struct;
}

public static class Vector256
{
+     public static Vector256<T> AddSaturate<T>     (Vector256<T> left, Vector256<T> right) where T : struct;
+     public static Vector256<T> SubtractSaturate<T>(Vector256<T> left, Vector256<T> right) where T : struct;
}

public static class Vector512
{
+     public static Vector512<T> AddSaturate<T>     (Vector512<T> left, Vector512<T> right) where T : struct;
+     public static Vector512<T> SubtractSaturate<T>(Vector512<T> left, Vector512<T> right) where T : struct;
}

NOTE: SSE and AVX only accelerate byte, sbyte, short and ushort. AdvSimd supports more types.

@EgorBo EgorBo added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Feb 23, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Feb 23, 2023
@EgorBo
Copy link
Member Author

EgorBo commented Feb 23, 2023

cc @tannergooding

@tannergooding tannergooding added area-System.Runtime.Intrinsics api-ready-for-review API is ready for review, it is NOT ready for implementation and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation untriaged New issue has not been triaged by the area owner labels Feb 23, 2023
@tannergooding tannergooding added this to the 8.0.0 milestone Feb 23, 2023
@ghost
Copy link

ghost commented Feb 23, 2023

Tagging subscribers to this area: @dotnet/area-system-runtime-intrinsics
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

I hit lack of these crossplatform helpers when I was doing "parse hex" work in #82521 - ended up with local functions. These APIs seem to present in SSE/AVX and AdvSimd and can be easily exposed as cross-platform helpers. Some places in BCL might benefit from this too, e.g.

if (AdvSimd.IsSupported)
{
charIsThreeByteUtf8Encoded = AdvSimd.AddSaturate(utf16Data, vector7800);
mask = GetNonAsciiBytes(AdvSimd.Or(charIsNonAscii, charIsThreeByteUtf8Encoded).AsByte(), bitMask128);
}
else
{
charIsThreeByteUtf8Encoded = Sse2.AddSaturate(utf16Data, vector7800);
mask = (uint)Sse2.MoveMask(Sse2.Or(charIsNonAscii, charIsThreeByteUtf8Encoded).AsByte());
}

API Proposal

namespace System.Runtime.Intrinsics;

public static class Vector128
{
+   public static Vector128<sbyte> AddSaturate(Vector128<sbyte> left, Vector128<sbyte> right);
+   public static Vector128<byte> AddSaturate(Vector128<byte> left, Vector128<byte> right);
+   public static Vector128<short> AddSaturate(Vector128<short> left, Vector128<short> right);
+   public static Vector128<ushort> AddSaturate(Vector128<ushort> left, Vector128<ushort> right);

+   public static Vector128<sbyte> SubtractSaturate(Vector128<sbyte> left, Vector128<sbyte> right);
+   public static Vector128<byte> SubtractSaturate(Vector128<byte> left, Vector128<byte> right);
+   public static Vector128<short> SubtractSaturate(Vector128<short> left, Vector128<short> right);
+   public static Vector128<ushort> SubtractSaturate(Vector128<ushort> left, Vector128<ushort> right);
}

public static class Vector256
{
+   public static Vector256<sbyte> AddSaturate(Vector256<sbyte> left, Vector256<sbyte> right);
+   public static Vector256<byte> AddSaturate(Vector256<byte> left, Vector256<byte> right);
+   public static Vector256<short> AddSaturate(Vector256<short> left, Vector256<short> right);
+   public static Vector256<ushort> AddSaturate(Vector256<ushort> left, Vector256<ushort> right);

+   public static Vector256<sbyte> SubtractSaturate(Vector256<sbyte> left, Vector256<sbyte> right);
+   public static Vector256<byte> SubtractSaturate(Vector256<byte> left, Vector256<byte> right);
+   public static Vector256<short> SubtractSaturate(Vector256<short> left, Vector256<short> right);
+   public static Vector256<ushort> SubtractSaturate(Vector256<ushort> left, Vector256<ushort> right);
}

NOTE: AdvSimd supports more types, so these are just common denominators

Author: EgorBo
Assignees: -
Labels:

area-System.Runtime.Intrinsics, api-ready-for-review

Milestone: -

@bartonjs
Copy link
Member

bartonjs commented Mar 23, 2023

Video

  • The AddSaturate name is consistent with the intrinsics
  • We squared the circle to also include Vector, Vector64, and Vector512
namespace System.Runtime.Intrinsics;

public static partial class Vector
{
      public static Vector<T>   AddSaturate(Vector<T>   left, Vector<T>   right);
      public static Vector<T>   SubtractSaturate(Vector<T>   left, Vector<T>   right);
}

public static partial class Vector64
{
      public static Vector64<T>   AddSaturate(Vector64<T>   left, Vector64<T>   right);
      public static Vector64<T>   SubtractSaturate(Vector64<T>   left, Vector64<T>   right);
}

public static partial class Vector128
{
      public static Vector128<T>   AddSaturate(Vector128<T>   left, Vector128<T>   right);
      public static Vector128<T>   SubtractSaturate(Vector128<T>   left, Vector128<T>   right);
}

public static partial class Vector256
{
      public static Vector256<T>   AddSaturate(Vector256<T>   left, Vector256<T>   right);
      public static Vector256<T>   SubtractSaturate(Vector256<T>   left, Vector256<T>   right);
}

public static partial class Vector512
{
      public static Vector512<T>   AddSaturate(Vector512<T>   left, Vector512<T>   right);
      public static Vector512<T>   SubtractSaturate(Vector512<T>   left, Vector512<T>   right);
}

@bartonjs bartonjs added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for review, it is NOT ready for implementation labels Mar 23, 2023
@tannergooding tannergooding modified the milestones: 8.0.0, Future Jul 24, 2023
@tannergooding
Copy link
Member

Not going to land this for .NET 8; we can take a PR anytime after the repo opens for .NET 9 changes

@EgorBo EgorBo added the help wanted [up-for-grabs] Good issue for external contributors label Aug 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.Intrinsics help wanted [up-for-grabs] Good issue for external contributors
Projects
None yet
Development

No branches or pull requests

3 participants