Skip to content

[API Proposal]: TensorPrimitives brought up to par with Math and generic math interfaces #96451

Closed

Description

@stephentoub

Background and motivation

As noted in #94553 (comment), for post-.NET 8, we're planning to augment TensorPrimitives in three ways:

  1. Generic versions of these methods in order to handle other numerical types beyond float
  2. Additional generic methods for all the operations on the generic math interfaces that aren't currently on TensorPrimitives
  3. Additional generic methods to have good coverage of further relevant operations ala BLAS / LAPACK

(1) was approved in #94553 and implemented in #94555.

This issue covers (2).

(3) still needs to be proposed subsequently.

API Proposal

namespace System.Numerics.Tensors

public static class TensorPrimitives
{
    // Methods without existing overloads
+   public static void Acos<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void AcosPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void Acosh<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IHyperbolicFunctions<T>;
+   public static void Asin<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void AsinPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void Asinh<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IHyperbolicFunctions<T>;
+   public static void Atan<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void AtanPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void Atan2<T>(ReadOnlySpan<T> y, ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void Atan2Pi<T>(ReadOnlySpan<T> y, ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void Atanh<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IHyperbolicFunctions<T>;
+   public static void BitwiseAnd<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
+   public static void BitwiseAnd<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
+   public static void BitwiseOr<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
+   public static void BitwiseOr<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
+   public static void Cbrt<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IRootFunctions<T>;
+   public static void Ceiling<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPoint<T>;
+   public static void ConvertChecked<TFrom, TTo>(ReadOnlySpan<TFrom> source, Span<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
+   public static void ConvertSaturating<TFrom, TTo>(ReadOnlySpan<TFrom> source, Span<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
+   public static void ConvertTruncating<TFrom, TTo>(ReadOnlySpan<TFrom> source, Span<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
+   public static void CopySign<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> sign, Span<T> destination) where T : INumber<T>;
+   public static void CopySign<T>(ReadOnlySpan<T> x, T sign, Span<T> destination) where T : INumber<T>;
+   public static void Cos<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void CosPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void DegreesToRadians<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void ExpM1<T>(ReadOnlySpan<T> x) where T : IExponentialFunctions<TSelf>;
+   public static void Exp2<T>(ReadOnlySpan<T> x) where T : IExponentialFunctions<TSelf>;
+   public static void Exp2M1<T>(ReadOnlySpan<T> x) where T : IExponentialFunctions<TSelf>;
+   public static void Exp10<T>(ReadOnlySpan<T> x) where T : IExponentialFunctions<TSelf>;
+   public static void Exp10M1<T>(ReadOnlySpan<T> x) where T : IExponentialFunctions<TSelf>;
+   public static void Floor<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPoint<T>;
+   public static void FusedMultiplyAdd<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, ReadOnlySpan<T> addend, Span<T> destination) where T : IAdditionOperators<T, T, T>, IMultiplyOperators<T, T, T>;
+   public static void FusedMultiplyAdd<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T addend, Span<T> destination) where T : IAdditionOperators<T, T, T>, IMultiplyOperators<T, T, T>;
+   public static void FusedMultiplyAdd<T>(ReadOnlySpan<T> x, T y, ReadOnlySpan<T> addend, Span<T> destination) where T : IAdditionOperators<T, T, T>, IMultiplyOperators<T, T, T>;
+   public static void Hypot<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IRootFunctions<T>;
+   public static void Ieee754Remainder<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void Ieee754Remainder<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void Ieee754Remainder<T>(T x, ReadOnlySpan<T> y, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void LeadingZeroCount<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IBinaryInteger<T>;
+   public static void ILogB<T>(ReadOnlySpan<T> x, Span<int> destination) where T : IFloatingPointIeee754<T>;
+   public static void Lerp<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, ReadOnlySpan<T> amount, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void Lerp<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T amount, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void Lerp<T>(ReadOnlySpan<T> x, T y, ReadOnlySpan<T> amount, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void Log<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : ILogarithmicFunctions<T>;
+   public static void Log<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : ILogarithmicFunctions<T>;
+   public static void Log10<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ILogarithmicFunctions<T>;
+   public static void LogP1<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ILogarithmicFunctions<T>;
+   public static void Log2P1<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ILogarithmicFunctions<T>;
+   public static void Log10P1<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ILogarithmicFunctions<T>;
+   public static void OnesComplement<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
+   public static void PopCount<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IBinaryInteger<T>;
+   public static void Pow<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IPowerFunctions<T>;
+   public static void Pow<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : IPowerFunctions<T>;
+   public static void Pow<T>(T x, ReadOnlySpan<T> y, Span<T> destination) where T : IPowerFunctions<T>;
+   public static void RadiansToDegrees<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void Reciprocal<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPoint<T>;
+   public static void ReciprocalEstimate<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void ReciprocalSqrt<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void ReciprocalSqrtEstimate<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void RootN<T>(ReadOnlySpan<T> x, int n, Span<T> destination) where T : IRootFunctions<T>;
+   public static void RotateLeft<T>(ReadOnlySpan<T> x, int rotateAmount, Span<T> destination) where T : IBinaryInteger<T>;
+   public static void RotateRight<T>(ReadOnlySpan<T> x, int rotateAmount, Span<T> destination) where T : IBinaryInteger<T>;
+   public static void Round<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPoint<T>;
+   public static void Round<T>(ReadOnlySpan<T> x, MidpointRounding mode, Span<T> destination) where T : IFloatingPoint<T>;
+   public static void Round<T>(ReadOnlySpan<T> x, int digits, Span<T> destination) where T : IFloatingPoint<T>;
+   public static void Round<T>(ReadOnlySpan<T> x, int digits, MidpointRounding mode, Span<T> destination) where T : IFloatingPoint<T>;
+   public static void ScaleB<T>(ReadOnlySpan<T> x, int n, Span<T> destination) where T : IFloatingPointIeee754<T>;
+   public static void ShiftLeft<T>(ReadOnlySpan<T> x, int shiftAmount, Span<T> destination) where T : IBinaryInteger<T>;
+   public static void ShiftRightArithmetic<T>(ReadOnlySpan<T> x, int shiftAmount, Span<T> destination) where T : IBinaryInteger<T>;
+   public static void ShiftRightLogical<T>(ReadOnlySpan<T> x, int shiftAmount, Span<T> destination) where T : IBinaryInteger<T>;
+   public static void Sin<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void SinCos<T>(ReadOnlySpan<T> x, Span<T> sinDestination, Span<T> cosDestination) where T : ITrigonometricFunctions<T>;
+   public static void SinCosPi<T>(ReadOnlySpan<T> x, Span<T> sinPiDestination, Span<T> cosPiDestination) where T : ITrigonometricFunctions<T>;
+   public static void SinPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void Sqrt<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IRootFunctions<T>;
+   public static void Tan<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void TanPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
+   public static void TrailingZeroCount<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IBinaryInteger<T>;
+   public static void Truncate<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPoint<T>;
+   public static void Xor<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
+   public static void Xor<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;

    // Overloads of existing methods
+   public static void Divide<T>(T x, ReadOnlySpan<T> y, Span<T> destination) where T : IDivisionOperators<T, T, T>;
+   public static void Max<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : INumber<T>;
+   public static void MaxMagnitude<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : INumber<T>;
+   public static void Min<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : INumber<T>;
+   public static void MinMagnitude<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : INumber<T>;
+   public static void Subtract<T>(T x, ReadOnlySpan<T> y, Span<T> destination) where T : ISubtractionOperators<T, T, T>;
}

API Usage

float[] values = ...;
float[] destination = ...;
TensorPrimitives.Log10(values, destination);

Alternative Designs

No response

Risks

No response

Activity

  1. added
    api-suggestionEarly API idea and discussion, it is NOT ready for implementation
    on Jan 3, 2024
  2. added this to the 9.0.0 milestone on Jan 3, 2024
  3. stephentoub commented on Jan 8, 2024

    @stephentoub
    MemberAuthor

    @tannergooding, any feedback on this or can this batch be marked as ready for review?

  4. added
    api-ready-for-reviewAPI is ready for review, it is NOT ready for implementation
    and removed
    api-suggestionEarly API idea and discussion, it is NOT ready for implementation
    on Jan 14, 2024
  5. stephentoub commented on Jan 14, 2024

    @stephentoub
    MemberAuthor

    @tannergooding, I've marked it as ready for review.

  6. tannergooding commented on Jan 16, 2024

    @tannergooding
    Member

    Removed IEEERemainder as that's the "old" name and was replaced by Ieee754Remainder with generic math.

    The notable APIs (which aren't comparisons) that are missing are:

    PopCount
    LeadingZeroCount
    TrailingZeroCount
    
    RotateLeft
    RotateRight
    ShiftLeft
    ShiftRightLogical
    ShiftRightArithmetic
    
    BitwiseAnd
    BitwiseOr
    ExclusiveOr
    OnesComplement
    
    Decrement
    Increment
    
    Round
    
    BitIncrement
    BitDecrement
    
    FusedMultiplyAdd
    
    DegreesToRadians
    RadiansToDegrees
    
    SinCos
    SinCosPi
    

    FusedMultiplyAdd is one we should consider addressing with an additional MultiplyAddEstimate overload. SinCos and SinCosPi have two outputs, but can save a lot of compute time.

  7. stephentoub commented on Jan 16, 2024

    @stephentoub
    MemberAuthor

    The notable APIs (which aren't comparisons) that are missing are

    Missing and important to add? If so:

    • What would the shape of the SinCos{Pi} ones be?
    • What would the shape of Round be?
  8. 1 remaining item

  9. stephentoub commented on Jan 17, 2024

    @stephentoub
    MemberAuthor

    I updated the proposal.

    Two questions:

    • I matched the generic math interfaces, so e.g. PopCount writes to a Span<T>, but I don't understand why PopCount returns the number of bits as a T but a method like RotateLeft accepts a number of bits as an int. Should PopCount use Span<int> as the destination here? Or we're really trying to accomodate numbers with more than 2 billion bits?
    • You wrote "ExclusiveOr" above, but we use "Xor" in most other places, so I changed it to "BitwiseXor".
  10. tannergooding commented on Jan 17, 2024

    @tannergooding
    Member

    I matched the generic math interfaces, so e.g. PopCount writes to a Span, but I don't understand why PopCount returns the number of bits as a T but a method like RotateLeft accepts a number of bits as an int. Should PopCount use Span as the destination here? Or we're really trying to accomodate numbers with more than 2 billion bits?

    It matches how acceleration typically works. PopCount, LeadingZeroCount, and TrailingZeroCount typically returns a result as the same size it took as an input, which then allows its continued use as part of the general algorithm.

    On the other hand, shifting typically expects a constant (in which case it works best as an int since that's the natural type for literals) or it takes it as a small integer input (typically a byte), C# also had the historical limitation that the shift amount could only be int. At the time, we notably made a decision that 2^31 - 1 bits was enough for everyone (with regards to numbers). Both as that is a significantly huge value and because it simplified the handling of APIs dealing with Span<T> as it ensured users didn't need to consider partial copies, huge shifts, etc. However, the underlying IShiftOperators API was left open for users to define their own additional APIs that could take other types, if that made sense for their own scenarios.

    You wrote "ExclusiveOr" above, but we use "Xor" in most other places, so I changed it to "BitwiseXor".

    Sounds good to me. I had just written the names down as they appeared in the API docs (op_ExclusiveOr) and didn't think beyond that 😆

  11. stephentoub commented on Jan 17, 2024

    @stephentoub
    MemberAuthor

    Should BitwiseOnesComplement be BitwiseNot instead?

  12. tannergooding commented on Jan 17, 2024

    @tannergooding
    Member

    For Vector64/128/256/512<T> we matched the names given to Vector<T> in 2014, which was:

    • AndNot
    • BitwiseAnd
    • OnesComplement
    • BitwiseOr
    • Xor

    Which overall aren't self-consistent, but its what was chosen for them. It might be convenient to match them here as well, particularly since they are effectively just wrappers over the Vector APIs in many cases.

  13. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on Jan 19, 2024
  14. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Jan 22, 2024
  15. stephentoub commented on Jan 22, 2024

    @stephentoub
    MemberAuthor

    Implemented for P1 (the Convert* methods for P2), but needs API review and fixing up according to any changes from that.

  16. bartonjs commented on Feb 6, 2024

    @bartonjs
    Member

    Video

    Looks good as proposed.

    namespace System.Numerics.Tensors
    
    public static class TensorPrimitives
    {
        // Methods without existing overloads
    +   public static void Acos<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void AcosPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void Acosh<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IHyperbolicFunctions<T>;
    +   public static void Asin<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void AsinPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void Asinh<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IHyperbolicFunctions<T>;
    +   public static void Atan<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void AtanPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void Atan2<T>(ReadOnlySpan<T> y, ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void Atan2Pi<T>(ReadOnlySpan<T> y, ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void Atanh<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IHyperbolicFunctions<T>;
    +   public static void BitwiseAnd<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
    +   public static void BitwiseAnd<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
    +   public static void BitwiseOr<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
    +   public static void BitwiseOr<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
    +   public static void Cbrt<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IRootFunctions<T>;
    +   public static void Ceiling<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPoint<T>;
    +   public static void ConvertChecked<TFrom, TTo>(ReadOnlySpan<TFrom> source, Span<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
    +   public static void ConvertSaturating<TFrom, TTo>(ReadOnlySpan<TFrom> source, Span<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
    +   public static void ConvertTruncating<TFrom, TTo>(ReadOnlySpan<TFrom> source, Span<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
    +   public static void CopySign<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> sign, Span<T> destination) where T : INumber<T>;
    +   public static void CopySign<T>(ReadOnlySpan<T> x, T sign, Span<T> destination) where T : INumber<T>;
    +   public static void Cos<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void CosPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void DegreesToRadians<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void ExpM1<T>(ReadOnlySpan<T> x) where T : IExponentialFunctions<TSelf>;
    +   public static void Exp2<T>(ReadOnlySpan<T> x) where T : IExponentialFunctions<TSelf>;
    +   public static void Exp2M1<T>(ReadOnlySpan<T> x) where T : IExponentialFunctions<TSelf>;
    +   public static void Exp10<T>(ReadOnlySpan<T> x) where T : IExponentialFunctions<TSelf>;
    +   public static void Exp10M1<T>(ReadOnlySpan<T> x) where T : IExponentialFunctions<TSelf>;
    +   public static void Floor<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPoint<T>;
    +   public static void FusedMultiplyAdd<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, ReadOnlySpan<T> addend, Span<T> destination) where T : IAdditionOperators<T, T, T>, IMultiplyOperators<T, T, T>;
    +   public static void FusedMultiplyAdd<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T addend, Span<T> destination) where T : IAdditionOperators<T, T, T>, IMultiplyOperators<T, T, T>;
    +   public static void FusedMultiplyAdd<T>(ReadOnlySpan<T> x, T y, ReadOnlySpan<T> addend, Span<T> destination) where T : IAdditionOperators<T, T, T>, IMultiplyOperators<T, T, T>;
    +   public static void Hypot<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IRootFunctions<T>;
    +   public static void Ieee754Remainder<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void Ieee754Remainder<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void Ieee754Remainder<T>(T x, ReadOnlySpan<T> y, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void LeadingZeroCount<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IBinaryInteger<T>;
    +   public static void ILogB<T>(ReadOnlySpan<T> x, Span<int> destination) where T : IFloatingPointIeee754<T>;
    +   public static void Lerp<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, ReadOnlySpan<T> amount, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void Lerp<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, T amount, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void Lerp<T>(ReadOnlySpan<T> x, T y, ReadOnlySpan<T> amount, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void Log<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : ILogarithmicFunctions<T>;
    +   public static void Log<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : ILogarithmicFunctions<T>;
    +   public static void Log10<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ILogarithmicFunctions<T>;
    +   public static void LogP1<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ILogarithmicFunctions<T>;
    +   public static void Log2P1<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ILogarithmicFunctions<T>;
    +   public static void Log10P1<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ILogarithmicFunctions<T>;
    +   public static void OnesComplement<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
    +   public static void PopCount<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IBinaryInteger<T>;
    +   public static void Pow<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IPowerFunctions<T>;
    +   public static void Pow<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : IPowerFunctions<T>;
    +   public static void Pow<T>(T x, ReadOnlySpan<T> y, Span<T> destination) where T : IPowerFunctions<T>;
    +   public static void RadiansToDegrees<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void Reciprocal<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPoint<T>;
    +   public static void ReciprocalEstimate<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void ReciprocalSqrt<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void ReciprocalSqrtEstimate<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void RootN<T>(ReadOnlySpan<T> x, int n, Span<T> destination) where T : IRootFunctions<T>;
    +   public static void RotateLeft<T>(ReadOnlySpan<T> x, int rotateAmount, Span<T> destination) where T : IBinaryInteger<T>;
    +   public static void RotateRight<T>(ReadOnlySpan<T> x, int rotateAmount, Span<T> destination) where T : IBinaryInteger<T>;
    +   public static void Round<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPoint<T>;
    +   public static void Round<T>(ReadOnlySpan<T> x, MidpointRounding mode, Span<T> destination) where T : IFloatingPoint<T>;
    +   public static void Round<T>(ReadOnlySpan<T> x, int digits, Span<T> destination) where T : IFloatingPoint<T>;
    +   public static void Round<T>(ReadOnlySpan<T> x, int digits, MidpointRounding mode, Span<T> destination) where T : IFloatingPoint<T>;
    +   public static void ScaleB<T>(ReadOnlySpan<T> x, int n, Span<T> destination) where T : IFloatingPointIeee754<T>;
    +   public static void ShiftLeft<T>(ReadOnlySpan<T> x, int shiftAmount, Span<T> destination) where T : IBinaryInteger<T>;
    +   public static void ShiftRightArithmetic<T>(ReadOnlySpan<T> x, int shiftAmount, Span<T> destination) where T : IBinaryInteger<T>;
    +   public static void ShiftRightLogical<T>(ReadOnlySpan<T> x, int shiftAmount, Span<T> destination) where T : IBinaryInteger<T>;
    +   public static void Sin<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void SinCos<T>(ReadOnlySpan<T> x, Span<T> sinDestination, Span<T> cosDestination) where T : ITrigonometricFunctions<T>;
    +   public static void SinCosPi<T>(ReadOnlySpan<T> x, Span<T> sinPiDestination, Span<T> cosPiDestination) where T : ITrigonometricFunctions<T>;
    +   public static void SinPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void Sqrt<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IRootFunctions<T>;
    +   public static void Tan<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void TanPi<T>(ReadOnlySpan<T> x, Span<T> destination) where T : ITrigonometricFunctions<T>;
    +   public static void TrailingZeroCount<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IBinaryInteger<T>;
    +   public static void Truncate<T>(ReadOnlySpan<T> x, Span<T> destination) where T : IFloatingPoint<T>;
    +   public static void Xor<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
    +   public static void Xor<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : IBitwiseOperators<T, T, T>;
    
        // Overloads of existing methods
    +   public static void Divide<T>(T x, ReadOnlySpan<T> y, Span<T> destination) where T : IDivisionOperators<T, T, T>;
    +   public static void Max<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : INumber<T>;
    +   public static void MaxMagnitude<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : INumber<T>;
    +   public static void Min<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : INumber<T>;
    +   public static void MinMagnitude<T>(ReadOnlySpan<T> x, T y, Span<T> destination) where T : INumber<T>;
    +   public static void Subtract<T>(T x, ReadOnlySpan<T> y, Span<T> destination) where T : ISubtractionOperators<T, T, T>;
    }
  17. added
    api-approvedAPI was approved in API review, it can be implemented
    and removed
    api-ready-for-reviewAPI is ready for review, it is NOT ready for implementation
    on Feb 6, 2024
  18. stephentoub commented on Feb 6, 2024

    @stephentoub
    MemberAuthor

    This was implemented.

  19. locked and limited conversation to collaborators on Mar 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions