dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.05k stars 4.69k forks source link

[API Proposal]: Add BitwiseAndNot To TensorPrimitives #105307

Open LEI-Hongfaan opened 2 months ago

LEI-Hongfaan commented 2 months ago

Background and motivation

Certain architectures have specialized instructions to compute the AND NOT operation efficiently. By using these instructions, we can perform bitwise operations faster.

API Proposal

 namespace System.Numerics.Tensors {
   public static class TensorPrimitives {
+    public static void BitwiseAndNot<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : System.Numerics.IBitwiseOperators<T, T, T>;
+    public static void BitwiseAndNot<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : System.Numerics.IBitwiseOperators<T, T, T>;
+    public static void BitwiseAndNot<T>(T x, ReadOnlySpan<T> y, Span<T> destination) where T : System.Numerics.IBitwiseOperators<T, T, T>;
   }
 }

 namespace System.Numerics {
   public interface IBitwiseOperators<TSelf,TOther,TResult> where TSelf : IBitwiseOperators<TSelf, TOther, TResult> {
+    public static abstract TResult BitwiseAndNot(TSelf left, TOther right);
   }
 }

API Usage

For example, when performing a bitwise AND operation on BigInteger values, if x is nonnegative and y is negative, then x & y = x & ~(abs(y) - 1). In code, this would look like:

TensorPrimitives.BitwiseAndNot(xRemainingUpperBits, yRemainingUpperBits, resultRemainingUpperBits);

Alternative Designs

  1. Use AndNot instead of BitwiseAndNot
    1. Put the base case BitwiseAndNot in another interface.
    2. Do not add additional constraints on T.

Risks

No response

dotnet-policy-service[bot] commented 2 months ago

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

huoyaoyuan commented 2 months ago

public static abstract TResult BitwiseAndNot(TSelf left, TOther right);

Adding abstract method is a breaking change and unacceptable. Instead, this should be a static virtual method with fallback implementation.