From 0c2e82e7d478cbba2eed6f4425dd9ee22c4b811b Mon Sep 17 00:00:00 2001 From: Aleksei Smirnov Date: Wed, 24 Jul 2024 22:11:33 +0300 Subject: [PATCH] Use new System.Numerics.Tensors library for DataFrame arithmetic operations (.net8) (#7179) * Add dependency to the latest System.Numerics.Tensors library * Initial implementation of NumericArithmetic for net8 and TensorPrimitives * Use CompositeArithmetic * Refcatoring, using .net8 features to improve performance and code readability * Remove needless changes * Fix build * Update System.Numerics.Tensors lib --- .../Computations/Arithmetic.cs | 116 +- .../Computations/Arithmetic.net8.cs | 736 +++ .../Computations/Arithmetic.netstandard.cs | 5446 +++++++++++++++++ .../Computations/Arithmetic.netstandard.tt | 199 + .../Computations/Arithmetic.tt | 185 - .../Computations/Arithmetics.cs | 5394 ---------------- .../Computations/Arithmetics.tt | 171 - .../Microsoft.Data.Analysis.csproj | 30 +- .../DataFrameTests.BinaryOperations.cs | 9 + 9 files changed, 6412 insertions(+), 5874 deletions(-) create mode 100644 src/Microsoft.Data.Analysis/Computations/Arithmetic.net8.cs create mode 100644 src/Microsoft.Data.Analysis/Computations/Arithmetic.netstandard.cs create mode 100644 src/Microsoft.Data.Analysis/Computations/Arithmetic.netstandard.tt delete mode 100644 src/Microsoft.Data.Analysis/Computations/Arithmetic.tt delete mode 100644 src/Microsoft.Data.Analysis/Computations/Arithmetics.cs delete mode 100644 src/Microsoft.Data.Analysis/Computations/Arithmetics.tt diff --git a/src/Microsoft.Data.Analysis/Computations/Arithmetic.cs b/src/Microsoft.Data.Analysis/Computations/Arithmetic.cs index 41d267dd6..b2ecd2ffa 100644 --- a/src/Microsoft.Data.Analysis/Computations/Arithmetic.cs +++ b/src/Microsoft.Data.Analysis/Computations/Arithmetic.cs @@ -1,73 +1,19 @@ - -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -// Generated from Arithmetic.tt. Do not modify directly - using System; -using System.Numerics; -using System.Runtime.CompilerServices; +using System.Collections.Generic; +using System.Text; namespace Microsoft.Data.Analysis { - //////////////////////////////////////// - //Factory Class // - //////////////////////////////////////// - - internal static class Arithmetic - { - public static IArithmetic GetArithmetic() - where T : unmanaged - { - if (typeof(T) == typeof(bool)) - return (IArithmetic)new BoolArithmetic(); - else if (typeof(T) == typeof(byte)) - return (IArithmetic)new ByteArithmetic(); - else if (typeof(T) == typeof(char)) - return (IArithmetic)new CharArithmetic(); - else if (typeof(T) == typeof(decimal)) - return (IArithmetic)new DecimalArithmetic(); - else if (typeof(T) == typeof(double)) - return (IArithmetic)new DoubleArithmetic(); - else if (typeof(T) == typeof(float)) - return (IArithmetic)new FloatArithmetic(); - else if (typeof(T) == typeof(int)) - return (IArithmetic)new IntArithmetic(); - else if (typeof(T) == typeof(long)) - return (IArithmetic)new LongArithmetic(); - else if (typeof(T) == typeof(sbyte)) - return (IArithmetic)new SByteArithmetic(); - else if (typeof(T) == typeof(short)) - return (IArithmetic)new ShortArithmetic(); - else if (typeof(T) == typeof(uint)) - return (IArithmetic)new UIntArithmetic(); - else if (typeof(T) == typeof(ulong)) - return (IArithmetic)new ULongArithmetic(); - else if (typeof(T) == typeof(ushort)) - return (IArithmetic)new UShortArithmetic(); - else if (typeof(T) == typeof(DateTime)) - return (IArithmetic)new DateTimeArithmetic(); - throw new NotSupportedException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref Vector AsVector(ref T start, int offset) - where T : struct => ref Unsafe.As>(ref Unsafe.Add(ref start, offset)); - } - - - //////////////////////////////////////// - //Base Class for Arithmetic // - //////////////////////////////////////// - internal class Arithmetic : IArithmetic where T : unmanaged { public static IArithmetic Instance { get; } = Arithmetic.GetArithmetic(); - - //Binary operations + #region Binary operations public void HandleOperation(BinaryOperation operation, ReadOnlySpan x, ReadOnlySpan y, Span destination) { @@ -172,9 +118,9 @@ namespace Microsoft.Data.Analysis throw new NotSupportedException(); } + #endregion - - //Binary Int operations + #region Binary Int operations public void HandleOperation(BinaryIntOperation operation, ReadOnlySpan x, int y, Span destination) { @@ -188,9 +134,9 @@ namespace Microsoft.Data.Analysis break; } } + #endregion - - //Comparison operations + #region Comparison operations public void HandleOperation(ComparisonOperation operation, ReadOnlySpan x, ReadOnlySpan y, Span destination) { @@ -241,88 +187,54 @@ namespace Microsoft.Data.Analysis break; } } + #endregion - - //Protected methods + #region Protected methods protected virtual void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Add(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void Add(T x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Subtract(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void Subtract(T x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Multiply(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void Multiply(T x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Divide(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void Divide(T x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Modulo(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void Modulo(T x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); + protected virtual T Divide(T x, T y) => throw new NotSupportedException(); + protected virtual T Modulo(T x, T y) => throw new NotSupportedException(); + protected virtual void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void And(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void And(T x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Or(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void Or(T x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void Xor(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void Xor(T x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); protected virtual void LeftShift(ReadOnlySpan x, int y, Span destination) => throw new NotSupportedException(); - protected virtual void RightShift(ReadOnlySpan x, int y, Span destination) => throw new NotSupportedException(); protected virtual void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void ElementwiseEquals(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void ElementwiseNotEquals(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void ElementwiseLessThanOrEqual(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void ElementwiseGreaterThan(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - protected virtual void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); - protected virtual void ElementwiseLessThan(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - - protected virtual T Divide(T x, T y) => throw new NotSupportedException(); - - protected virtual T Modulo(T x, T y) => throw new NotSupportedException(); + #endregion } } diff --git a/src/Microsoft.Data.Analysis/Computations/Arithmetic.net8.cs b/src/Microsoft.Data.Analysis/Computations/Arithmetic.net8.cs new file mode 100644 index 000000000..e3854e1ce --- /dev/null +++ b/src/Microsoft.Data.Analysis/Computations/Arithmetic.net8.cs @@ -0,0 +1,736 @@ + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if NET8_0_OR_GREATER + +using System; +using System.Numerics; +using System.Numerics.Tensors; + +namespace Microsoft.Data.Analysis +{ + internal static partial class Arithmetic + { + #region Nested classes for Operations + private interface IBitwiseOperations + where T : unmanaged + { + static abstract void And(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void And(ReadOnlySpan x, T y, Span destination); + static abstract void And(T x, ReadOnlySpan y, Span destination); + static abstract void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void Or(ReadOnlySpan x, T y, Span destination); + static abstract void Or(T x, ReadOnlySpan y, Span destination); + static abstract void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void Xor(ReadOnlySpan x, T y, Span destination); + static abstract void Xor(T x, ReadOnlySpan y, Span destination); + } + + private interface IShiftOperations + where T : unmanaged + { + static abstract void LeftShift(ReadOnlySpan x, int shiftAmount, Span destination); + static abstract void RightShift(ReadOnlySpan x, int shiftAmount, Span destination); + } + + private interface INumericOperations + where T : unmanaged + { + static abstract void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void Add(ReadOnlySpan x, T y, Span destination); + static abstract void Add(T x, ReadOnlySpan y, Span destination); + static abstract void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void Subtract(ReadOnlySpan x, T y, Span destination); + static abstract void Subtract(T x, ReadOnlySpan y, Span destination); + static abstract void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void Multiply(ReadOnlySpan x, T y, Span destination); + static abstract void Multiply(T x, ReadOnlySpan y, Span destination); + static abstract void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void Divide(ReadOnlySpan x, T y, Span destination); + static abstract void Divide(T x, ReadOnlySpan y, Span destination); + static abstract T Divide(T x, T y); + static abstract void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void Modulo(ReadOnlySpan x, T y, Span destination); + static abstract void Modulo(T x, ReadOnlySpan y, Span destination); + static abstract T Modulo(T x, T y); + + static abstract void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void ElementwiseEquals(ReadOnlySpan x, T y, Span destination); + static abstract void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void ElementwiseNotEquals(ReadOnlySpan x, T y, Span destination); + static abstract void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, T y, Span destination); + static abstract void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void ElementwiseLessThanOrEqual(ReadOnlySpan x, T y, Span destination); + static abstract void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void ElementwiseGreaterThan(ReadOnlySpan x, T y, Span destination); + static abstract void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination); + static abstract void ElementwiseLessThan(ReadOnlySpan x, T y, Span destination); + } + + private readonly struct BitwiseOperations : IBitwiseOperations + where T : unmanaged, IBitwiseOperators + { + public static void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) => TensorPrimitives.BitwiseAnd(x, y, destination); + public static void And(ReadOnlySpan x, T y, Span destination) => TensorPrimitives.BitwiseAnd(x, y, destination); + public static void And(T x, ReadOnlySpan y, Span destination) => TensorPrimitives.BitwiseAnd(y, x, destination); + public static void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) => TensorPrimitives.BitwiseOr(x, y, destination); + public static void Or(ReadOnlySpan x, T y, Span destination) => TensorPrimitives.BitwiseOr(x, y, destination); + public static void Or(T x, ReadOnlySpan y, Span destination) => TensorPrimitives.BitwiseOr(y, x, destination); + public static void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) => TensorPrimitives.Xor(x, y, destination); + public static void Xor(ReadOnlySpan x, T y, Span destination) => TensorPrimitives.Xor(x, y, destination); + public static void Xor(T x, ReadOnlySpan y, Span destination) => TensorPrimitives.Xor(y, x, destination); + } + + private readonly struct ShiftOperations : IShiftOperations + where T : unmanaged, IShiftOperators + { + public static void LeftShift(ReadOnlySpan x, int shiftAmount, Span destination) => TensorPrimitives.ShiftLeft(x, shiftAmount, destination); + public static void RightShift(ReadOnlySpan x, int shiftAmount, Span destination) => TensorPrimitives.ShiftRightArithmetic(x, shiftAmount, destination); + } + + private readonly struct NumericOperations : INumericOperations + where T : unmanaged, INumber + { + public static void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) => TensorPrimitives.Add(x, y, destination); + public static void Add(ReadOnlySpan x, T y, Span destination) => TensorPrimitives.Add(x, y, destination); + public static void Add(T x, ReadOnlySpan y, Span destination) => TensorPrimitives.Add(y, x, destination); + public static void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) => TensorPrimitives.Subtract(x, y, destination); + public static void Subtract(ReadOnlySpan x, T y, Span destination) => TensorPrimitives.Subtract(x, y, destination); + public static void Subtract(T x, ReadOnlySpan y, Span destination) => TensorPrimitives.Subtract(x, y, destination); + public static void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) => TensorPrimitives.Multiply(x, y, destination); + public static void Multiply(ReadOnlySpan x, T y, Span destination) => TensorPrimitives.Multiply(x, y, destination); + public static void Multiply(T x, ReadOnlySpan y, Span destination) => TensorPrimitives.Multiply(y, x, destination); + public static void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) => TensorPrimitives.Divide(x, y, destination); + public static void Divide(ReadOnlySpan x, T y, Span destination) => TensorPrimitives.Divide(x, y, destination); + public static void Divide(T x, ReadOnlySpan y, Span destination) => TensorPrimitives.Divide(x, y, destination); + public static T Divide(T x, T y) => x / y; + + public static void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = x[i] % y[i]; + } + } + + public static void Modulo(ReadOnlySpan x, T y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = x[i] % y; + } + } + + public static void Modulo(T x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < y.Length; i++) + { + destination[i] = x % y[i]; + } + } + + public static T Modulo(T x, T y) => x % y; + + public static void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + public static void ElementwiseEquals(ReadOnlySpan x, T y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + public static void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + public static void ElementwiseNotEquals(ReadOnlySpan x, T y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + public static void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + public static void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, T y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + public static void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + public static void ElementwiseLessThanOrEqual(ReadOnlySpan x, T y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + public static void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + public static void ElementwiseGreaterThan(ReadOnlySpan x, T y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + public static void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + public static void ElementwiseLessThan(ReadOnlySpan x, T y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + #endregion + + #region Nested classes for Arithmetics + private class CompositeArithmetic : IArithmetic + where T : unmanaged + where TNumericOperations : struct, INumericOperations + { + public virtual void HandleOperation(BinaryOperation operation, ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + switch (operation) + { + case BinaryOperation.Add: + TNumericOperations.Add(x, y, destination); + break; + case BinaryOperation.Subtract: + TNumericOperations.Subtract(x, y, destination); + break; + case BinaryOperation.Multiply: + TNumericOperations.Multiply(x, y, destination); + break; + case BinaryOperation.Divide: + TNumericOperations.Divide(x, y, destination); + break; + case BinaryOperation.Modulo: + TNumericOperations.Modulo(x, y, destination); + break; + default: + throw new NotSupportedException(); + } + } + + public virtual void HandleOperation(BinaryOperation operation, ReadOnlySpan x, T y, Span destination) + { + switch (operation) + { + case BinaryOperation.Add: + TNumericOperations.Add(x, y, destination); + break; + case BinaryOperation.Subtract: + TNumericOperations.Subtract(x, y, destination); + break; + case BinaryOperation.Multiply: + TNumericOperations.Multiply(x, y, destination); + break; + case BinaryOperation.Divide: + TNumericOperations.Divide(x, y, destination); + break; + case BinaryOperation.Modulo: + TNumericOperations.Modulo(x, y, destination); + break; + default: + throw new NotSupportedException(); + } + } + + public virtual void HandleOperation(BinaryOperation operation, T x, ReadOnlySpan y, Span destination) + { + switch (operation) + { + case BinaryOperation.Add: + TNumericOperations.Add(x, y, destination); + break; + case BinaryOperation.Subtract: + TNumericOperations.Subtract(x, y, destination); + break; + case BinaryOperation.Multiply: + TNumericOperations.Multiply(x, y, destination); + break; + case BinaryOperation.Divide: + TNumericOperations.Divide(x, y, destination); + break; + case BinaryOperation.Modulo: + TNumericOperations.Modulo(x, y, destination); + break; + default: + throw new NotSupportedException(); + } + } + + public T HandleOperation(BinaryOperation operation, T x, T y) + { + if (operation == BinaryOperation.Divide) + return TNumericOperations.Divide(x, y); + + if (operation == BinaryOperation.Modulo) + return TNumericOperations.Modulo(x, y); + + throw new NotSupportedException(); + } + + public virtual void HandleOperation(BinaryIntOperation operation, ReadOnlySpan x, int y, Span destination) + { + throw new NotSupportedException(); + } + + public void HandleOperation(ComparisonOperation operation, ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + switch (operation) + { + case ComparisonOperation.ElementwiseEquals: + TNumericOperations.ElementwiseEquals(x, y, destination); + break; + case ComparisonOperation.ElementwiseNotEquals: + TNumericOperations.ElementwiseNotEquals(x, y, destination); + break; + case ComparisonOperation.ElementwiseGreaterThanOrEqual: + TNumericOperations.ElementwiseGreaterThanOrEqual(x, y, destination); + break; + case ComparisonOperation.ElementwiseLessThanOrEqual: + TNumericOperations.ElementwiseLessThanOrEqual(x, y, destination); + break; + case ComparisonOperation.ElementwiseGreaterThan: + TNumericOperations.ElementwiseGreaterThan(x, y, destination); + break; + case ComparisonOperation.ElementwiseLessThan: + TNumericOperations.ElementwiseLessThan(x, y, destination); + break; + default: + throw new NotSupportedException(); + } + } + + public void HandleOperation(ComparisonOperation operation, ReadOnlySpan x, T y, Span destination) + { + switch (operation) + { + case ComparisonOperation.ElementwiseEquals: + TNumericOperations.ElementwiseEquals(x, y, destination); + break; + case ComparisonOperation.ElementwiseNotEquals: + TNumericOperations.ElementwiseNotEquals(x, y, destination); + break; + case ComparisonOperation.ElementwiseGreaterThanOrEqual: + TNumericOperations.ElementwiseGreaterThanOrEqual(x, y, destination); + break; + case ComparisonOperation.ElementwiseLessThanOrEqual: + TNumericOperations.ElementwiseLessThanOrEqual(x, y, destination); + break; + case ComparisonOperation.ElementwiseGreaterThan: + TNumericOperations.ElementwiseGreaterThan(x, y, destination); + break; + case ComparisonOperation.ElementwiseLessThan: + TNumericOperations.ElementwiseLessThan(x, y, destination); + break; + default: + throw new NotSupportedException(); + } + } + } + + private class CompositeArithmetic : CompositeArithmetic, IArithmetic + where T : unmanaged + where TNumericOperations : struct, INumericOperations + where TBitwiseOperations : struct, IBitwiseOperations + { + public override void HandleOperation(BinaryOperation operation, ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + switch (operation) + { + case BinaryOperation.And: + TBitwiseOperations.And(x, y, destination); + return; + case BinaryOperation.Or: + TBitwiseOperations.Or(x, y, destination); + return; + case BinaryOperation.Xor: + TBitwiseOperations.Xor(x, y, destination); + return; + } + + base.HandleOperation(operation, x, y, destination); + } + + public override void HandleOperation(BinaryOperation operation, ReadOnlySpan x, T y, Span destination) + { + switch (operation) + { + case BinaryOperation.And: + TBitwiseOperations.And(x, y, destination); + return; + case BinaryOperation.Or: + TBitwiseOperations.Or(x, y, destination); + return; + case BinaryOperation.Xor: + TBitwiseOperations.Xor(x, y, destination); + return; + } + + base.HandleOperation(operation, x, y, destination); + } + + public override void HandleOperation(BinaryOperation operation, T x, ReadOnlySpan y, Span destination) + { + switch (operation) + { + case BinaryOperation.And: + TBitwiseOperations.And(x, y, destination); + return; + case BinaryOperation.Or: + TBitwiseOperations.Or(x, y, destination); + return; + case BinaryOperation.Xor: + TBitwiseOperations.Xor(x, y, destination); + return; + } + + base.HandleOperation(operation, x, y, destination); + } + } + + private class CompositeArithmetic : CompositeArithmetic, IArithmetic + where T : unmanaged + where TNumericOperations : struct, INumericOperations + where TBitwiseOperations : struct, IBitwiseOperations + where TShiftOperations : struct, IShiftOperations + { + + public override void HandleOperation(BinaryIntOperation operation, ReadOnlySpan x, int y, Span destination) + { + switch (operation) + { + case BinaryIntOperation.LeftShift: + TShiftOperations.LeftShift(x, y, destination); + break; + case BinaryIntOperation.RightShift: + TShiftOperations.RightShift(x, y, destination); + break; + default: + throw new NotSupportedException(); + } + } + } + + //Special case + internal class DateTimeArithmetic : Arithmetic + { + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, DateTime y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, DateTime y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, DateTime y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, DateTime y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, DateTime y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, DateTime y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + + internal class BoolArithmetic : Arithmetic + { + protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] & y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, bool y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] & y); + i++; + } + } + + protected override void And(bool x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (bool)(x & y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] | y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, bool y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] | y); + i++; + } + } + + protected override void Or(bool x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (bool)(x | y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] ^ y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, bool y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] ^ y); + i++; + } + } + + protected override void Xor(bool x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (bool)(x ^ y[i]); + i++; + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, bool y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, bool y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + } + #endregion + + internal static IArithmetic GetArithmetic() + where T : unmanaged + { + if (typeof(T) == typeof(double)) + return (IArithmetic)new CompositeArithmetic, BitwiseOperations>(); + if (typeof(T) == typeof(float)) + return (IArithmetic)new CompositeArithmetic, BitwiseOperations>(); + if (typeof(T) == typeof(int)) + return (IArithmetic)new CompositeArithmetic, BitwiseOperations, ShiftOperations>(); + if (typeof(T) == typeof(long)) + return (IArithmetic)new CompositeArithmetic, BitwiseOperations, ShiftOperations>(); + if (typeof(T) == typeof(sbyte)) + return (IArithmetic)new CompositeArithmetic, BitwiseOperations, ShiftOperations>(); + if (typeof(T) == typeof(short)) + return (IArithmetic)new CompositeArithmetic, BitwiseOperations, ShiftOperations>(); + if (typeof(T) == typeof(uint)) + return (IArithmetic)new CompositeArithmetic, BitwiseOperations, ShiftOperations>(); + if (typeof(T) == typeof(ulong)) + return (IArithmetic)new CompositeArithmetic, BitwiseOperations, ShiftOperations>(); + if (typeof(T) == typeof(ushort)) + return (IArithmetic)new CompositeArithmetic, BitwiseOperations, ShiftOperations>(); + if (typeof(T) == typeof(byte)) + return (IArithmetic)new CompositeArithmetic, BitwiseOperations, ShiftOperations>(); + if (typeof(T) == typeof(char)) + return (IArithmetic)new CompositeArithmetic, BitwiseOperations, ShiftOperations>(); + if (typeof(T) == typeof(decimal)) + return (IArithmetic)new CompositeArithmetic>(); + if (typeof(T) == typeof(DateTime)) + return (IArithmetic)new DateTimeArithmetic(); + if (typeof(T) == typeof(bool)) + return (IArithmetic)new BoolArithmetic(); + throw new NotSupportedException(); + } + } +} +#endif diff --git a/src/Microsoft.Data.Analysis/Computations/Arithmetic.netstandard.cs b/src/Microsoft.Data.Analysis/Computations/Arithmetic.netstandard.cs new file mode 100644 index 000000000..eb3049b2a --- /dev/null +++ b/src/Microsoft.Data.Analysis/Computations/Arithmetic.netstandard.cs @@ -0,0 +1,5446 @@ + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Generated from Arithmetic.tt. Do not modify directly + +#if !NET8_0_OR_GREATER + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Data.Analysis +{ + //////////////////////////////////////// + //Factory Class // + //////////////////////////////////////// + + internal static partial class Arithmetic + { + #region Nested classes for Arithmetics + + internal class BoolArithmetic : Arithmetic + { + + protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] & y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, bool y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] & y); + i++; + } + } + + protected override void And(bool x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (bool)(x & y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] | y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, bool y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] | y); + i++; + } + } + + protected override void Or(bool x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (bool)(x | y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] ^ y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, bool y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (bool)(x[i] ^ y); + i++; + } + } + + protected override void Xor(bool x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (bool)(x ^ y[i]); + i++; + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, bool y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, bool y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + } + internal class ByteArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref byte xRef = ref MemoryMarshal.GetReference(x); + ref byte yRef = ref MemoryMarshal.GetReference(y); + ref byte dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (byte)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, byte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] + y); + i++; + } + } + + protected override void Add(byte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (byte)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref byte xRef = ref MemoryMarshal.GetReference(x); + ref byte yRef = ref MemoryMarshal.GetReference(y); + ref byte dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (byte)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, byte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] - y); + i++; + } + } + + protected override void Subtract(byte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (byte)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref byte xRef = ref MemoryMarshal.GetReference(x); + ref byte yRef = ref MemoryMarshal.GetReference(y); + ref byte dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (byte)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, byte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] * y); + i++; + } + } + + protected override void Multiply(byte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (byte)(x * y[i]); + i++; + } + } + + protected override byte Divide(byte x, byte y) + { + return (byte)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref byte xRef = ref MemoryMarshal.GetReference(x); + ref byte yRef = ref MemoryMarshal.GetReference(y); + ref byte dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (byte)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, byte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] / y); + i++; + } + } + + protected override void Divide(byte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (byte)(x / y[i]); + i++; + } + } + + protected override byte Modulo(byte x, byte y) + { + return (byte)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, byte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] % y); + i++; + } + } + + protected override void Modulo(byte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (byte)(x % y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] & y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, byte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] & y); + i++; + } + } + + protected override void And(byte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (byte)(x & y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] | y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, byte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] | y); + i++; + } + } + + protected override void Or(byte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (byte)(x | y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] ^ y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, byte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (byte)(x[i] ^ y); + i++; + } + } + + protected override void Xor(byte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (byte)(x ^ y[i]); + i++; + } + } + + protected override void LeftShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (byte)(x[i] << y); + } + + protected override void RightShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (byte)(x[i] >> y); + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, byte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, byte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, byte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, byte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, byte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, byte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class CharArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref char xRef = ref MemoryMarshal.GetReference(x); + ref char yRef = ref MemoryMarshal.GetReference(y); + ref char dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (char)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, char y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] + y); + i++; + } + } + + protected override void Add(char x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (char)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref char xRef = ref MemoryMarshal.GetReference(x); + ref char yRef = ref MemoryMarshal.GetReference(y); + ref char dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (char)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, char y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] - y); + i++; + } + } + + protected override void Subtract(char x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (char)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref char xRef = ref MemoryMarshal.GetReference(x); + ref char yRef = ref MemoryMarshal.GetReference(y); + ref char dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (char)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, char y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] * y); + i++; + } + } + + protected override void Multiply(char x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (char)(x * y[i]); + i++; + } + } + + protected override char Divide(char x, char y) + { + return (char)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref char xRef = ref MemoryMarshal.GetReference(x); + ref char yRef = ref MemoryMarshal.GetReference(y); + ref char dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (char)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, char y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] / y); + i++; + } + } + + protected override void Divide(char x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (char)(x / y[i]); + i++; + } + } + + protected override char Modulo(char x, char y) + { + return (char)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, char y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] % y); + i++; + } + } + + protected override void Modulo(char x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (char)(x % y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] & y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, char y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] & y); + i++; + } + } + + protected override void And(char x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (char)(x & y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] | y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, char y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] | y); + i++; + } + } + + protected override void Or(char x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (char)(x | y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] ^ y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, char y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (char)(x[i] ^ y); + i++; + } + } + + protected override void Xor(char x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (char)(x ^ y[i]); + i++; + } + } + + protected override void LeftShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (char)(x[i] << y); + } + + protected override void RightShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (char)(x[i] >> y); + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, char y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, char y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, char y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, char y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, char y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, char y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class DecimalArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (decimal)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, decimal y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (decimal)(x[i] + y); + i++; + } + } + + protected override void Add(decimal x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (decimal)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (decimal)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, decimal y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (decimal)(x[i] - y); + i++; + } + } + + protected override void Subtract(decimal x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (decimal)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (decimal)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, decimal y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (decimal)(x[i] * y); + i++; + } + } + + protected override void Multiply(decimal x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (decimal)(x * y[i]); + i++; + } + } + + protected override decimal Divide(decimal x, decimal y) + { + return (decimal)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (decimal)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, decimal y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (decimal)(x[i] / y); + i++; + } + } + + protected override void Divide(decimal x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (decimal)(x / y[i]); + i++; + } + } + + protected override decimal Modulo(decimal x, decimal y) + { + return (decimal)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (decimal)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, decimal y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (decimal)(x[i] % y); + i++; + } + } + + protected override void Modulo(decimal x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (decimal)(x % y[i]); + i++; + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, decimal y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, decimal y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, decimal y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, decimal y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, decimal y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, decimal y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class DoubleArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref double xRef = ref MemoryMarshal.GetReference(x); + ref double yRef = ref MemoryMarshal.GetReference(y); + ref double dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (double)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, double y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (double)(x[i] + y); + i++; + } + } + + protected override void Add(double x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (double)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref double xRef = ref MemoryMarshal.GetReference(x); + ref double yRef = ref MemoryMarshal.GetReference(y); + ref double dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (double)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, double y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (double)(x[i] - y); + i++; + } + } + + protected override void Subtract(double x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (double)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref double xRef = ref MemoryMarshal.GetReference(x); + ref double yRef = ref MemoryMarshal.GetReference(y); + ref double dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (double)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, double y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (double)(x[i] * y); + i++; + } + } + + protected override void Multiply(double x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (double)(x * y[i]); + i++; + } + } + + protected override double Divide(double x, double y) + { + return (double)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref double xRef = ref MemoryMarshal.GetReference(x); + ref double yRef = ref MemoryMarshal.GetReference(y); + ref double dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (double)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, double y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (double)(x[i] / y); + i++; + } + } + + protected override void Divide(double x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (double)(x / y[i]); + i++; + } + } + + protected override double Modulo(double x, double y) + { + return (double)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (double)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, double y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (double)(x[i] % y); + i++; + } + } + + protected override void Modulo(double x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (double)(x % y[i]); + i++; + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, double y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, double y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, double y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, double y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, double y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, double y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class FloatArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (float)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, float y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (float)(x[i] + y); + i++; + } + } + + protected override void Add(float x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (float)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (float)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, float y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (float)(x[i] - y); + i++; + } + } + + protected override void Subtract(float x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (float)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (float)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, float y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (float)(x[i] * y); + i++; + } + } + + protected override void Multiply(float x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (float)(x * y[i]); + i++; + } + } + + protected override float Divide(float x, float y) + { + return (float)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref float xRef = ref MemoryMarshal.GetReference(x); + ref float yRef = ref MemoryMarshal.GetReference(y); + ref float dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (float)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, float y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (float)(x[i] / y); + i++; + } + } + + protected override void Divide(float x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (float)(x / y[i]); + i++; + } + } + + protected override float Modulo(float x, float y) + { + return (float)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (float)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, float y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (float)(x[i] % y); + i++; + } + } + + protected override void Modulo(float x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (float)(x % y[i]); + i++; + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, float y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, float y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, float y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, float y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, float y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, float y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class IntArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref int xRef = ref MemoryMarshal.GetReference(x); + ref int yRef = ref MemoryMarshal.GetReference(y); + ref int dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (int)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, int y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] + y); + i++; + } + } + + protected override void Add(int x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (int)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref int xRef = ref MemoryMarshal.GetReference(x); + ref int yRef = ref MemoryMarshal.GetReference(y); + ref int dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (int)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, int y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] - y); + i++; + } + } + + protected override void Subtract(int x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (int)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref int xRef = ref MemoryMarshal.GetReference(x); + ref int yRef = ref MemoryMarshal.GetReference(y); + ref int dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (int)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, int y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] * y); + i++; + } + } + + protected override void Multiply(int x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (int)(x * y[i]); + i++; + } + } + + protected override int Divide(int x, int y) + { + return (int)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref int xRef = ref MemoryMarshal.GetReference(x); + ref int yRef = ref MemoryMarshal.GetReference(y); + ref int dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (int)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, int y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] / y); + i++; + } + } + + protected override void Divide(int x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (int)(x / y[i]); + i++; + } + } + + protected override int Modulo(int x, int y) + { + return (int)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, int y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] % y); + i++; + } + } + + protected override void Modulo(int x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (int)(x % y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] & y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, int y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] & y); + i++; + } + } + + protected override void And(int x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (int)(x & y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] | y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, int y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] | y); + i++; + } + } + + protected override void Or(int x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (int)(x | y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] ^ y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, int y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (int)(x[i] ^ y); + i++; + } + } + + protected override void Xor(int x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (int)(x ^ y[i]); + i++; + } + } + + protected override void LeftShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (int)(x[i] << y); + } + + protected override void RightShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (int)(x[i] >> y); + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class LongArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref long xRef = ref MemoryMarshal.GetReference(x); + ref long yRef = ref MemoryMarshal.GetReference(y); + ref long dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (long)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, long y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] + y); + i++; + } + } + + protected override void Add(long x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (long)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref long xRef = ref MemoryMarshal.GetReference(x); + ref long yRef = ref MemoryMarshal.GetReference(y); + ref long dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (long)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, long y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] - y); + i++; + } + } + + protected override void Subtract(long x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (long)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref long xRef = ref MemoryMarshal.GetReference(x); + ref long yRef = ref MemoryMarshal.GetReference(y); + ref long dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (long)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, long y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] * y); + i++; + } + } + + protected override void Multiply(long x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (long)(x * y[i]); + i++; + } + } + + protected override long Divide(long x, long y) + { + return (long)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref long xRef = ref MemoryMarshal.GetReference(x); + ref long yRef = ref MemoryMarshal.GetReference(y); + ref long dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (long)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, long y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] / y); + i++; + } + } + + protected override void Divide(long x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (long)(x / y[i]); + i++; + } + } + + protected override long Modulo(long x, long y) + { + return (long)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, long y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] % y); + i++; + } + } + + protected override void Modulo(long x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (long)(x % y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] & y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, long y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] & y); + i++; + } + } + + protected override void And(long x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (long)(x & y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] | y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, long y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] | y); + i++; + } + } + + protected override void Or(long x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (long)(x | y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] ^ y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, long y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (long)(x[i] ^ y); + i++; + } + } + + protected override void Xor(long x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (long)(x ^ y[i]); + i++; + } + } + + protected override void LeftShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (long)(x[i] << y); + } + + protected override void RightShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (long)(x[i] >> y); + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, long y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, long y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, long y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, long y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, long y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, long y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class SByteArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref sbyte xRef = ref MemoryMarshal.GetReference(x); + ref sbyte yRef = ref MemoryMarshal.GetReference(y); + ref sbyte dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, sbyte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] + y); + i++; + } + } + + protected override void Add(sbyte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (sbyte)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref sbyte xRef = ref MemoryMarshal.GetReference(x); + ref sbyte yRef = ref MemoryMarshal.GetReference(y); + ref sbyte dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, sbyte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] - y); + i++; + } + } + + protected override void Subtract(sbyte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (sbyte)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref sbyte xRef = ref MemoryMarshal.GetReference(x); + ref sbyte yRef = ref MemoryMarshal.GetReference(y); + ref sbyte dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, sbyte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] * y); + i++; + } + } + + protected override void Multiply(sbyte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (sbyte)(x * y[i]); + i++; + } + } + + protected override sbyte Divide(sbyte x, sbyte y) + { + return (sbyte)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref sbyte xRef = ref MemoryMarshal.GetReference(x); + ref sbyte yRef = ref MemoryMarshal.GetReference(y); + ref sbyte dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, sbyte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] / y); + i++; + } + } + + protected override void Divide(sbyte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (sbyte)(x / y[i]); + i++; + } + } + + protected override sbyte Modulo(sbyte x, sbyte y) + { + return (sbyte)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, sbyte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] % y); + i++; + } + } + + protected override void Modulo(sbyte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (sbyte)(x % y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] & y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, sbyte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] & y); + i++; + } + } + + protected override void And(sbyte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (sbyte)(x & y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] | y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, sbyte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] | y); + i++; + } + } + + protected override void Or(sbyte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (sbyte)(x | y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] ^ y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, sbyte y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (sbyte)(x[i] ^ y); + i++; + } + } + + protected override void Xor(sbyte x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (sbyte)(x ^ y[i]); + i++; + } + } + + protected override void LeftShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (sbyte)(x[i] << y); + } + + protected override void RightShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (sbyte)(x[i] >> y); + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, sbyte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, sbyte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, sbyte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, sbyte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, sbyte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, sbyte y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class ShortArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref short xRef = ref MemoryMarshal.GetReference(x); + ref short yRef = ref MemoryMarshal.GetReference(y); + ref short dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (short)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, short y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] + y); + i++; + } + } + + protected override void Add(short x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (short)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref short xRef = ref MemoryMarshal.GetReference(x); + ref short yRef = ref MemoryMarshal.GetReference(y); + ref short dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (short)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, short y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] - y); + i++; + } + } + + protected override void Subtract(short x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (short)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref short xRef = ref MemoryMarshal.GetReference(x); + ref short yRef = ref MemoryMarshal.GetReference(y); + ref short dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (short)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, short y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] * y); + i++; + } + } + + protected override void Multiply(short x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (short)(x * y[i]); + i++; + } + } + + protected override short Divide(short x, short y) + { + return (short)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref short xRef = ref MemoryMarshal.GetReference(x); + ref short yRef = ref MemoryMarshal.GetReference(y); + ref short dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (short)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, short y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] / y); + i++; + } + } + + protected override void Divide(short x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (short)(x / y[i]); + i++; + } + } + + protected override short Modulo(short x, short y) + { + return (short)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, short y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] % y); + i++; + } + } + + protected override void Modulo(short x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (short)(x % y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] & y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, short y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] & y); + i++; + } + } + + protected override void And(short x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (short)(x & y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] | y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, short y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] | y); + i++; + } + } + + protected override void Or(short x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (short)(x | y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] ^ y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, short y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (short)(x[i] ^ y); + i++; + } + } + + protected override void Xor(short x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (short)(x ^ y[i]); + i++; + } + } + + protected override void LeftShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (short)(x[i] << y); + } + + protected override void RightShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (short)(x[i] >> y); + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, short y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, short y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, short y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, short y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, short y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, short y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class UIntArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref uint xRef = ref MemoryMarshal.GetReference(x); + ref uint yRef = ref MemoryMarshal.GetReference(y); + ref uint dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (uint)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, uint y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] + y); + i++; + } + } + + protected override void Add(uint x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (uint)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref uint xRef = ref MemoryMarshal.GetReference(x); + ref uint yRef = ref MemoryMarshal.GetReference(y); + ref uint dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (uint)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, uint y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] - y); + i++; + } + } + + protected override void Subtract(uint x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (uint)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref uint xRef = ref MemoryMarshal.GetReference(x); + ref uint yRef = ref MemoryMarshal.GetReference(y); + ref uint dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (uint)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, uint y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] * y); + i++; + } + } + + protected override void Multiply(uint x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (uint)(x * y[i]); + i++; + } + } + + protected override uint Divide(uint x, uint y) + { + return (uint)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref uint xRef = ref MemoryMarshal.GetReference(x); + ref uint yRef = ref MemoryMarshal.GetReference(y); + ref uint dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (uint)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, uint y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] / y); + i++; + } + } + + protected override void Divide(uint x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (uint)(x / y[i]); + i++; + } + } + + protected override uint Modulo(uint x, uint y) + { + return (uint)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, uint y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] % y); + i++; + } + } + + protected override void Modulo(uint x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (uint)(x % y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] & y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, uint y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] & y); + i++; + } + } + + protected override void And(uint x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (uint)(x & y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] | y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, uint y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] | y); + i++; + } + } + + protected override void Or(uint x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (uint)(x | y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] ^ y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, uint y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (uint)(x[i] ^ y); + i++; + } + } + + protected override void Xor(uint x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (uint)(x ^ y[i]); + i++; + } + } + + protected override void LeftShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (uint)(x[i] << y); + } + + protected override void RightShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (uint)(x[i] >> y); + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, uint y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, uint y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, uint y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, uint y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, uint y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, uint y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class ULongArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref ulong xRef = ref MemoryMarshal.GetReference(x); + ref ulong yRef = ref MemoryMarshal.GetReference(y); + ref ulong dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, ulong y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] + y); + i++; + } + } + + protected override void Add(ulong x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ulong)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref ulong xRef = ref MemoryMarshal.GetReference(x); + ref ulong yRef = ref MemoryMarshal.GetReference(y); + ref ulong dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ulong y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] - y); + i++; + } + } + + protected override void Subtract(ulong x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ulong)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref ulong xRef = ref MemoryMarshal.GetReference(x); + ref ulong yRef = ref MemoryMarshal.GetReference(y); + ref ulong dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ulong y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] * y); + i++; + } + } + + protected override void Multiply(ulong x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ulong)(x * y[i]); + i++; + } + } + + protected override ulong Divide(ulong x, ulong y) + { + return (ulong)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref ulong xRef = ref MemoryMarshal.GetReference(x); + ref ulong yRef = ref MemoryMarshal.GetReference(y); + ref ulong dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, ulong y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] / y); + i++; + } + } + + protected override void Divide(ulong x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ulong)(x / y[i]); + i++; + } + } + + protected override ulong Modulo(ulong x, ulong y) + { + return (ulong)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, ulong y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] % y); + i++; + } + } + + protected override void Modulo(ulong x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ulong)(x % y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] & y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, ulong y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] & y); + i++; + } + } + + protected override void And(ulong x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ulong)(x & y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] | y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ulong y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] | y); + i++; + } + } + + protected override void Or(ulong x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ulong)(x | y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] ^ y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ulong y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ulong)(x[i] ^ y); + i++; + } + } + + protected override void Xor(ulong x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ulong)(x ^ y[i]); + i++; + } + } + + protected override void LeftShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (ulong)(x[i] << y); + } + + protected override void RightShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (ulong)(x[i] >> y); + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ulong y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ulong y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ulong y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ulong y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ulong y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ulong y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class UShortArithmetic : Arithmetic + { + + protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref ushort xRef = ref MemoryMarshal.GetReference(x); + ref ushort yRef = ref MemoryMarshal.GetReference(y); + ref ushort dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] + y[i]); + i++; + } + } + + protected override void Add(ReadOnlySpan x, ushort y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] + y); + i++; + } + } + + protected override void Add(ushort x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ushort)(x + y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref ushort xRef = ref MemoryMarshal.GetReference(x); + ref ushort yRef = ref MemoryMarshal.GetReference(y); + ref ushort dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] - y[i]); + i++; + } + } + + protected override void Subtract(ReadOnlySpan x, ushort y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] - y); + i++; + } + } + + protected override void Subtract(ushort x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ushort)(x - y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref ushort xRef = ref MemoryMarshal.GetReference(x); + ref ushort yRef = ref MemoryMarshal.GetReference(y); + ref ushort dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] * y[i]); + i++; + } + } + + protected override void Multiply(ReadOnlySpan x, ushort y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] * y); + i++; + } + } + + protected override void Multiply(ushort x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ushort)(x * y[i]); + i++; + } + } + + protected override ushort Divide(ushort x, ushort y) + { + return (ushort)(x / y); + } + + protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + if (Vector.IsHardwareAccelerated) + { + ref ushort xRef = ref MemoryMarshal.GetReference(x); + ref ushort yRef = ref MemoryMarshal.GetReference(y); + ref ushort dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] / y[i]); + i++; + } + } + + protected override void Divide(ReadOnlySpan x, ushort y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] / y); + i++; + } + } + + protected override void Divide(ushort x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ushort)(x / y[i]); + i++; + } + } + + protected override ushort Modulo(ushort x, ushort y) + { + return (ushort)(x % y); + } + + protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] % y[i]); + i++; + } + } + + protected override void Modulo(ReadOnlySpan x, ushort y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] % y); + i++; + } + } + + protected override void Modulo(ushort x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ushort)(x % y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] & y[i]); + i++; + } + } + + protected override void And(ReadOnlySpan x, ushort y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] & y); + i++; + } + } + + protected override void And(ushort x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ushort)(x & y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] | y[i]); + i++; + } + } + + protected override void Or(ReadOnlySpan x, ushort y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] | y); + i++; + } + } + + protected override void Or(ushort x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ushort)(x | y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] ^ y[i]); + i++; + } + } + + protected override void Xor(ReadOnlySpan x, ushort y, Span destination) + { + int i = 0; + + while (i < x.Length) + { + destination[i] = (ushort)(x[i] ^ y); + i++; + } + } + + protected override void Xor(ushort x, ReadOnlySpan y, Span destination) + { + int i = 0; + + while (i < y.Length) + { + destination[i] = (ushort)(x ^ y[i]); + i++; + } + } + + protected override void LeftShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (ushort)(x[i] << y); + } + + protected override void RightShift(ReadOnlySpan x, int y, Span destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (ushort)(x[i] >> y); + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, ushort y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ushort y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y[i]); + } + } + + protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ushort y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] >= y); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y[i]); + } + } + + protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ushort y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <= y); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y[i]); + } + } + + protected override void ElementwiseGreaterThan(ReadOnlySpan x, ushort y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] > y); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y[i]); + } + } + + protected override void ElementwiseLessThan(ReadOnlySpan x, ushort y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] < y); + } + } + } + internal class DateTimeArithmetic : Arithmetic + { + + protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y[i]); + } + } + + protected override void ElementwiseEquals(ReadOnlySpan x, DateTime y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] == y); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y[i]); + } + } + + protected override void ElementwiseNotEquals(ReadOnlySpan x, DateTime y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] != y); + } + } + } + #endregion + + internal static IArithmetic GetArithmetic() + where T : unmanaged + { + if (typeof(T) == typeof(bool)) + return (IArithmetic)new BoolArithmetic(); + else if (typeof(T) == typeof(byte)) + return (IArithmetic)new ByteArithmetic(); + else if (typeof(T) == typeof(char)) + return (IArithmetic)new CharArithmetic(); + else if (typeof(T) == typeof(decimal)) + return (IArithmetic)new DecimalArithmetic(); + else if (typeof(T) == typeof(double)) + return (IArithmetic)new DoubleArithmetic(); + else if (typeof(T) == typeof(float)) + return (IArithmetic)new FloatArithmetic(); + else if (typeof(T) == typeof(int)) + return (IArithmetic)new IntArithmetic(); + else if (typeof(T) == typeof(long)) + return (IArithmetic)new LongArithmetic(); + else if (typeof(T) == typeof(sbyte)) + return (IArithmetic)new SByteArithmetic(); + else if (typeof(T) == typeof(short)) + return (IArithmetic)new ShortArithmetic(); + else if (typeof(T) == typeof(uint)) + return (IArithmetic)new UIntArithmetic(); + else if (typeof(T) == typeof(ulong)) + return (IArithmetic)new ULongArithmetic(); + else if (typeof(T) == typeof(ushort)) + return (IArithmetic)new UShortArithmetic(); + else if (typeof(T) == typeof(DateTime)) + return (IArithmetic)new DateTimeArithmetic(); + throw new NotSupportedException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref Vector AsVector(ref T start, int offset) + where T : struct => ref Unsafe.As>(ref Unsafe.Add(ref start, offset)); + } +} +#endif \ No newline at end of file diff --git a/src/Microsoft.Data.Analysis/Computations/Arithmetic.netstandard.tt b/src/Microsoft.Data.Analysis/Computations/Arithmetic.netstandard.tt new file mode 100644 index 000000000..9eadc208a --- /dev/null +++ b/src/Microsoft.Data.Analysis/Computations/Arithmetic.netstandard.tt @@ -0,0 +1,199 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<#@ include file="$(ProjectDir)\ColumnArithmeticTemplate.ttinclude" #> +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// Generated from Arithmetic.tt. Do not modify directly + +#if !NET8_0_OR_GREATER + +using System; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Microsoft.Data.Analysis +{ + //////////////////////////////////////// + //Factory Class // + //////////////////////////////////////// + + internal static partial class Arithmetic + { + #region Nested classes for Arithmetics + +<# foreach (TypeConfiguration type in typeConfiguration) { #> + internal class <#=type.ClassPrefix#>Arithmetic : Arithmetic<<#=type.TypeName#>> + { +<# foreach (MethodConfiguration method in methodConfiguration) { #> +<# if (!((method.IsNumeric && !type.SupportsNumeric) || (method.IsBitwise && !type.SupportsBitwise) || (type.UnsupportedMethods.Contains(method.MethodName))) && method.Operator != null) { #> +<# if (method.MethodType == MethodType.Comparison) { #> + + protected override void <#=method.MethodName#>(ReadOnlySpan<<#=type.TypeName#>> x, ReadOnlySpan<<#=type.TypeName#>> y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <#= method.Operator #> y[i]); + } + } +<# } else if (method.MethodType == MethodType.ComparisonScalar) {#> + + protected override void <#=method.MethodName#>(ReadOnlySpan<<#=type.TypeName#>> x, <#=type.TypeName#> y, Span destination) + { + for (var i = 0; i < x.Length; i++) + { + destination[i] = (x[i] <#= method.Operator #> y); + } + } +<# } else if (method.MethodType == MethodType.Binary) { #> +<# if (method.MethodName == "Divide" || method.MethodName == "Modulo") { #> + + protected override <#=type.TypeName#> <#=method.MethodName#>(<#=type.TypeName#> x, <#=type.TypeName#> y) + { + return (<#=type.TypeName#>)(x <#= method.Operator #> y); + } +<# } #> + + protected override void <#=method.MethodName#>(ReadOnlySpan<<#=type.TypeName#>> x, ReadOnlySpan<<#=type.TypeName#>> y, Span<<#=type.TypeName#>> destination) + { + int i = 0; +<# if (method.SupportsVectorization && type.SupportsVectorization) { #> + if (Vector.IsHardwareAccelerated) + { + ref <#=type.TypeName#> xRef = ref MemoryMarshal.GetReference(x); + ref <#=type.TypeName#> yRef = ref MemoryMarshal.GetReference(y); + ref <#=type.TypeName#> dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector<<#=type.TypeName#>>.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) <#= method.Operator #> Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } +<# } #> + + while (i < x.Length) + { + destination[i] = (<#=type.TypeName#>)(x[i] <#= method.Operator #> y[i]); + i++; + } + } +<# } #> +<# else if (method.MethodType == MethodType.BinaryScalar) { #> + + protected override void <#=method.MethodName#>(ReadOnlySpan<<#=type.TypeName#>> x, <#=type.TypeName#> y, Span<<#=type.TypeName#>> destination) + { + int i = 0; +<# if (method.SupportsVectorization && type.SupportsVectorization) { #> + if (Vector.IsHardwareAccelerated) + { + ref <#=type.TypeName#> xRef = ref MemoryMarshal.GetReference(x); + ref <#=type.TypeName#> dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector<<#=type.TypeName#>>.Count; + var oneVectorFromEnd = x.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + Vector<<#=type.TypeName#>> yVec = new(y); + + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) <#= method.Operator #> yVec); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } +<# } #> + + while (i < x.Length) + { + destination[i] = (<#=type.TypeName#>)(x[i] <#= method.Operator #> y); + i++; + } + } + + protected override void <#=method.MethodName#>(<#=type.TypeName#> x, ReadOnlySpan<<#=type.TypeName#>> y, Span<<#=type.TypeName#>> destination) + { + int i = 0; +<# if (method.SupportsVectorization && type.SupportsVectorization) { #> + if (Vector.IsHardwareAccelerated) + { + ref <#=type.TypeName#> yRef = ref MemoryMarshal.GetReference(y); + ref <#=type.TypeName#> dRef = ref MemoryMarshal.GetReference(destination); + + var vectorSize = Vector<<#=type.TypeName#>>.Count; + var oneVectorFromEnd = y.Length - vectorSize; + + if (oneVectorFromEnd >= 0) + { + Vector<<#=type.TypeName#>> xVec = new(x); + + // Loop handling one vector at a time. + do + { + Arithmetic.AsVector(ref dRef, i) = (xVec <#= method.Operator #> Arithmetic.AsVector(ref yRef, i)); + + i += vectorSize; + } + while (i <= oneVectorFromEnd); + } + } +<# } #> + + while (i < y.Length) + { + destination[i] = (<#=type.TypeName#>)(x <#= method.Operator #> y[i]); + i++; + } + } +<# } #> +<# else if (method.MethodType == MethodType.BinaryInt) { #> + + protected override void <#=method.MethodName#>(ReadOnlySpan<<#=type.TypeName#>> x, int y, Span<<#=type.TypeName#>> destination) + { + for (var i = 0; i < x.Length; i++) + destination[i] = (<#=type.TypeName#>)(x[i] <#= method.Operator #> y); + } +<# } #> +<# } #> +<# } #> + } +<# } #> + #endregion + + internal static IArithmetic GetArithmetic() + where T : unmanaged + { +<# foreach (TypeConfiguration type in typeConfiguration) { #> + <#=GenerateIfStatementHeader(type)#> + return (IArithmetic)new <#=type.ClassPrefix#>Arithmetic(); +<# } #> + throw new NotSupportedException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref Vector AsVector(ref T start, int offset) + where T : struct => ref Unsafe.As>(ref Unsafe.Add(ref start, offset)); + } +} +#endif \ No newline at end of file diff --git a/src/Microsoft.Data.Analysis/Computations/Arithmetic.tt b/src/Microsoft.Data.Analysis/Computations/Arithmetic.tt deleted file mode 100644 index f0e84c501..000000000 --- a/src/Microsoft.Data.Analysis/Computations/Arithmetic.tt +++ /dev/null @@ -1,185 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ output extension=".cs" #> -<#@ include file="$(ProjectDir)\ColumnArithmeticTemplate.ttinclude" #> -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Generated from Arithmetic.tt. Do not modify directly - -using System; -using System.Numerics; -using System.Runtime.CompilerServices; - -namespace Microsoft.Data.Analysis -{ - //////////////////////////////////////// - //Factory Class // - //////////////////////////////////////// - - internal static class Arithmetic - { - public static IArithmetic GetArithmetic() - where T : unmanaged - { -<# foreach (TypeConfiguration type in typeConfiguration) { #> - <#=GenerateIfStatementHeader(type)#> - return (IArithmetic)new <#=type.ClassPrefix#>Arithmetic(); -<# } #> - throw new NotSupportedException(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ref Vector AsVector(ref T start, int offset) - where T : struct => ref Unsafe.As>(ref Unsafe.Add(ref start, offset)); - } - - - //////////////////////////////////////// - //Base Class for Arithmetic // - //////////////////////////////////////// - - internal class Arithmetic : IArithmetic - where T : unmanaged - { - public static IArithmetic Instance { get; } = Arithmetic.GetArithmetic(); - - - //Binary operations - - public void HandleOperation(BinaryOperation operation, ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - switch (operation) - { -<# foreach (MethodConfiguration method in methodConfiguration) { #> -<# if (method.MethodType == MethodType.Binary) { #> - case BinaryOperation.<#=method.MethodName#>: - <#=method.MethodName#>(x, y, destination); - break; -<# } #> -<# } #> - } - } - - public void HandleOperation(BinaryOperation operation, ReadOnlySpan x, T y, Span destination) - { - switch (operation) - { -<# foreach (MethodConfiguration method in methodConfiguration) { #> -<# if (method.MethodType == MethodType.BinaryScalar) { #> - case BinaryOperation.<#=method.MethodName#>: - <#=method.MethodName#>(x, y, destination); - break; -<# } #> -<# } #> - } - } - - public void HandleOperation(BinaryOperation operation, T x, ReadOnlySpan y, Span destination) - { - switch (operation) - { -<# foreach (MethodConfiguration method in methodConfiguration) { #> -<# if (method.MethodType == MethodType.BinaryScalar) { #> - case BinaryOperation.<#=method.MethodName#>: - <#=method.MethodName#>(x, y, destination); - break; -<# } #> -<# } #> - } - } - - public T HandleOperation(BinaryOperation operation, T x, T y) - { - if (operation == BinaryOperation.Divide) - return Divide(x, y); - - if (operation == BinaryOperation.Modulo) - return Modulo(x, y); - - throw new NotSupportedException(); - } - - - //Binary Int operations - - public void HandleOperation(BinaryIntOperation operation, ReadOnlySpan x, int y, Span destination) - { - switch (operation) - { -<# foreach (MethodConfiguration method in methodConfiguration) { #> -<# if (method.MethodType == MethodType.BinaryInt) { #> - case BinaryIntOperation.<#=method.MethodName#>: - <#=method.MethodName#>(x, y, destination); - break; -<# } #> -<# } #> - } - } - - - //Comparison operations - - public void HandleOperation(ComparisonOperation operation, ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - switch (operation) - { -<# foreach (MethodConfiguration method in methodConfiguration) { #> -<# if (method.MethodType == MethodType.Comparison) { #> - case ComparisonOperation.<#=method.MethodName#>: - <#=method.MethodName#>(x, y, destination); - break; -<# } #> -<# } #> - } - } - - public void HandleOperation(ComparisonOperation operation, ReadOnlySpan x, T y, Span destination) - { - switch (operation) - { -<# foreach (MethodConfiguration method in methodConfiguration) { #> -<# if (method.MethodType == MethodType.ComparisonScalar) { #> - case ComparisonOperation.<#=method.MethodName#>: - <#=method.MethodName#>(x, y, destination); - break; -<# } #> -<# } #> - } - } - - - //Protected methods -<# foreach (MethodConfiguration method in methodConfiguration) { #> -<# if (method.MethodType == MethodType.Comparison) { #> - - protected virtual void <#=method.MethodName#>(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); -<# } #> -<# else if (method.MethodType == MethodType.ComparisonScalar) { #> - - protected virtual void <#=method.MethodName#>(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); -<# } #> -<# else if (method.MethodType == MethodType.Binary) { #> - - protected virtual void <#=method.MethodName#>(ReadOnlySpan x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); -<# } else if (method.MethodType == MethodType.BinaryScalar) { #> - - protected virtual void <#=method.MethodName#>(ReadOnlySpan x, T y, Span destination) => throw new NotSupportedException(); - - protected virtual void <#=method.MethodName#>(T x, ReadOnlySpan y, Span destination) => throw new NotSupportedException(); -<# } else if (method.MethodType == MethodType.BinaryInt) { #> - - protected virtual void <#=method.MethodName#>(ReadOnlySpan x, int y, Span destination) => throw new NotSupportedException(); -<# } #> -<# } #> - - protected virtual T Divide(T x, T y) => throw new NotSupportedException(); - - protected virtual T Modulo(T x, T y) => throw new NotSupportedException(); - } -} diff --git a/src/Microsoft.Data.Analysis/Computations/Arithmetics.cs b/src/Microsoft.Data.Analysis/Computations/Arithmetics.cs deleted file mode 100644 index 30bbefff3..000000000 --- a/src/Microsoft.Data.Analysis/Computations/Arithmetics.cs +++ /dev/null @@ -1,5394 +0,0 @@ - -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Generated from Arithmetics.tt. Do not modify directly - -using System; -using System.Numerics; -using System.Runtime.InteropServices; - -namespace Microsoft.Data.Analysis -{ - internal class BoolArithmetic : Arithmetic - { - - protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (bool)(x[i] & y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, bool y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (bool)(x[i] & y); - i++; - } - } - - protected override void And(bool x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (bool)(x & y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (bool)(x[i] | y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, bool y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (bool)(x[i] | y); - i++; - } - } - - protected override void Or(bool x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (bool)(x | y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (bool)(x[i] ^ y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, bool y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (bool)(x[i] ^ y); - i++; - } - } - - protected override void Xor(bool x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (bool)(x ^ y[i]); - i++; - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, bool y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, bool y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - } - internal class ByteArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref byte xRef = ref MemoryMarshal.GetReference(x); - ref byte yRef = ref MemoryMarshal.GetReference(y); - ref byte dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (byte)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, byte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] + y); - i++; - } - } - - protected override void Add(byte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (byte)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref byte xRef = ref MemoryMarshal.GetReference(x); - ref byte yRef = ref MemoryMarshal.GetReference(y); - ref byte dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (byte)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, byte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] - y); - i++; - } - } - - protected override void Subtract(byte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (byte)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref byte xRef = ref MemoryMarshal.GetReference(x); - ref byte yRef = ref MemoryMarshal.GetReference(y); - ref byte dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (byte)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, byte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] * y); - i++; - } - } - - protected override void Multiply(byte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (byte)(x * y[i]); - i++; - } - } - - protected override byte Divide(byte x, byte y) - { - return (byte)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref byte xRef = ref MemoryMarshal.GetReference(x); - ref byte yRef = ref MemoryMarshal.GetReference(y); - ref byte dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (byte)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, byte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] / y); - i++; - } - } - - protected override void Divide(byte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (byte)(x / y[i]); - i++; - } - } - - protected override byte Modulo(byte x, byte y) - { - return (byte)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, byte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] % y); - i++; - } - } - - protected override void Modulo(byte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (byte)(x % y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] & y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, byte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] & y); - i++; - } - } - - protected override void And(byte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (byte)(x & y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] | y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, byte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] | y); - i++; - } - } - - protected override void Or(byte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (byte)(x | y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] ^ y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, byte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (byte)(x[i] ^ y); - i++; - } - } - - protected override void Xor(byte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (byte)(x ^ y[i]); - i++; - } - } - - protected override void LeftShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (byte)(x[i] << y); - } - - protected override void RightShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (byte)(x[i] >> y); - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, byte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, byte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, byte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, byte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, byte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, byte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class CharArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref char xRef = ref MemoryMarshal.GetReference(x); - ref char yRef = ref MemoryMarshal.GetReference(y); - ref char dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (char)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, char y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] + y); - i++; - } - } - - protected override void Add(char x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (char)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref char xRef = ref MemoryMarshal.GetReference(x); - ref char yRef = ref MemoryMarshal.GetReference(y); - ref char dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (char)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, char y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] - y); - i++; - } - } - - protected override void Subtract(char x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (char)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref char xRef = ref MemoryMarshal.GetReference(x); - ref char yRef = ref MemoryMarshal.GetReference(y); - ref char dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (char)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, char y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] * y); - i++; - } - } - - protected override void Multiply(char x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (char)(x * y[i]); - i++; - } - } - - protected override char Divide(char x, char y) - { - return (char)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref char xRef = ref MemoryMarshal.GetReference(x); - ref char yRef = ref MemoryMarshal.GetReference(y); - ref char dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (char)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, char y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] / y); - i++; - } - } - - protected override void Divide(char x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (char)(x / y[i]); - i++; - } - } - - protected override char Modulo(char x, char y) - { - return (char)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, char y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] % y); - i++; - } - } - - protected override void Modulo(char x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (char)(x % y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] & y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, char y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] & y); - i++; - } - } - - protected override void And(char x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (char)(x & y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] | y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, char y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] | y); - i++; - } - } - - protected override void Or(char x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (char)(x | y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] ^ y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, char y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (char)(x[i] ^ y); - i++; - } - } - - protected override void Xor(char x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (char)(x ^ y[i]); - i++; - } - } - - protected override void LeftShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (char)(x[i] << y); - } - - protected override void RightShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (char)(x[i] >> y); - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, char y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, char y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, char y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, char y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, char y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, char y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class DecimalArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (decimal)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, decimal y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (decimal)(x[i] + y); - i++; - } - } - - protected override void Add(decimal x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (decimal)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (decimal)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, decimal y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (decimal)(x[i] - y); - i++; - } - } - - protected override void Subtract(decimal x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (decimal)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (decimal)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, decimal y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (decimal)(x[i] * y); - i++; - } - } - - protected override void Multiply(decimal x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (decimal)(x * y[i]); - i++; - } - } - - protected override decimal Divide(decimal x, decimal y) - { - return (decimal)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (decimal)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, decimal y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (decimal)(x[i] / y); - i++; - } - } - - protected override void Divide(decimal x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (decimal)(x / y[i]); - i++; - } - } - - protected override decimal Modulo(decimal x, decimal y) - { - return (decimal)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (decimal)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, decimal y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (decimal)(x[i] % y); - i++; - } - } - - protected override void Modulo(decimal x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (decimal)(x % y[i]); - i++; - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, decimal y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, decimal y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, decimal y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, decimal y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, decimal y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, decimal y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class DoubleArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref double xRef = ref MemoryMarshal.GetReference(x); - ref double yRef = ref MemoryMarshal.GetReference(y); - ref double dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (double)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, double y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (double)(x[i] + y); - i++; - } - } - - protected override void Add(double x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (double)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref double xRef = ref MemoryMarshal.GetReference(x); - ref double yRef = ref MemoryMarshal.GetReference(y); - ref double dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (double)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, double y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (double)(x[i] - y); - i++; - } - } - - protected override void Subtract(double x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (double)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref double xRef = ref MemoryMarshal.GetReference(x); - ref double yRef = ref MemoryMarshal.GetReference(y); - ref double dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (double)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, double y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (double)(x[i] * y); - i++; - } - } - - protected override void Multiply(double x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (double)(x * y[i]); - i++; - } - } - - protected override double Divide(double x, double y) - { - return (double)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref double xRef = ref MemoryMarshal.GetReference(x); - ref double yRef = ref MemoryMarshal.GetReference(y); - ref double dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (double)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, double y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (double)(x[i] / y); - i++; - } - } - - protected override void Divide(double x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (double)(x / y[i]); - i++; - } - } - - protected override double Modulo(double x, double y) - { - return (double)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (double)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, double y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (double)(x[i] % y); - i++; - } - } - - protected override void Modulo(double x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (double)(x % y[i]); - i++; - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, double y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, double y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, double y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, double y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, double y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, double y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class FloatArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); - ref float dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (float)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, float y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (float)(x[i] + y); - i++; - } - } - - protected override void Add(float x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (float)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); - ref float dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (float)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, float y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (float)(x[i] - y); - i++; - } - } - - protected override void Subtract(float x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (float)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); - ref float dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (float)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, float y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (float)(x[i] * y); - i++; - } - } - - protected override void Multiply(float x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (float)(x * y[i]); - i++; - } - } - - protected override float Divide(float x, float y) - { - return (float)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref float xRef = ref MemoryMarshal.GetReference(x); - ref float yRef = ref MemoryMarshal.GetReference(y); - ref float dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (float)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, float y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (float)(x[i] / y); - i++; - } - } - - protected override void Divide(float x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (float)(x / y[i]); - i++; - } - } - - protected override float Modulo(float x, float y) - { - return (float)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (float)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, float y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (float)(x[i] % y); - i++; - } - } - - protected override void Modulo(float x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (float)(x % y[i]); - i++; - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, float y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, float y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, float y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, float y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, float y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, float y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class IntArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref int xRef = ref MemoryMarshal.GetReference(x); - ref int yRef = ref MemoryMarshal.GetReference(y); - ref int dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (int)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, int y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] + y); - i++; - } - } - - protected override void Add(int x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (int)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref int xRef = ref MemoryMarshal.GetReference(x); - ref int yRef = ref MemoryMarshal.GetReference(y); - ref int dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (int)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, int y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] - y); - i++; - } - } - - protected override void Subtract(int x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (int)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref int xRef = ref MemoryMarshal.GetReference(x); - ref int yRef = ref MemoryMarshal.GetReference(y); - ref int dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (int)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, int y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] * y); - i++; - } - } - - protected override void Multiply(int x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (int)(x * y[i]); - i++; - } - } - - protected override int Divide(int x, int y) - { - return (int)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref int xRef = ref MemoryMarshal.GetReference(x); - ref int yRef = ref MemoryMarshal.GetReference(y); - ref int dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (int)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, int y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] / y); - i++; - } - } - - protected override void Divide(int x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (int)(x / y[i]); - i++; - } - } - - protected override int Modulo(int x, int y) - { - return (int)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, int y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] % y); - i++; - } - } - - protected override void Modulo(int x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (int)(x % y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] & y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, int y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] & y); - i++; - } - } - - protected override void And(int x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (int)(x & y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] | y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, int y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] | y); - i++; - } - } - - protected override void Or(int x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (int)(x | y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] ^ y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, int y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (int)(x[i] ^ y); - i++; - } - } - - protected override void Xor(int x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (int)(x ^ y[i]); - i++; - } - } - - protected override void LeftShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (int)(x[i] << y); - } - - protected override void RightShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (int)(x[i] >> y); - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class LongArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref long xRef = ref MemoryMarshal.GetReference(x); - ref long yRef = ref MemoryMarshal.GetReference(y); - ref long dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (long)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, long y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] + y); - i++; - } - } - - protected override void Add(long x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (long)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref long xRef = ref MemoryMarshal.GetReference(x); - ref long yRef = ref MemoryMarshal.GetReference(y); - ref long dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (long)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, long y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] - y); - i++; - } - } - - protected override void Subtract(long x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (long)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref long xRef = ref MemoryMarshal.GetReference(x); - ref long yRef = ref MemoryMarshal.GetReference(y); - ref long dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (long)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, long y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] * y); - i++; - } - } - - protected override void Multiply(long x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (long)(x * y[i]); - i++; - } - } - - protected override long Divide(long x, long y) - { - return (long)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref long xRef = ref MemoryMarshal.GetReference(x); - ref long yRef = ref MemoryMarshal.GetReference(y); - ref long dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (long)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, long y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] / y); - i++; - } - } - - protected override void Divide(long x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (long)(x / y[i]); - i++; - } - } - - protected override long Modulo(long x, long y) - { - return (long)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, long y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] % y); - i++; - } - } - - protected override void Modulo(long x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (long)(x % y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] & y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, long y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] & y); - i++; - } - } - - protected override void And(long x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (long)(x & y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] | y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, long y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] | y); - i++; - } - } - - protected override void Or(long x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (long)(x | y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] ^ y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, long y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (long)(x[i] ^ y); - i++; - } - } - - protected override void Xor(long x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (long)(x ^ y[i]); - i++; - } - } - - protected override void LeftShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (long)(x[i] << y); - } - - protected override void RightShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (long)(x[i] >> y); - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, long y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, long y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, long y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, long y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, long y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, long y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class SByteArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref sbyte xRef = ref MemoryMarshal.GetReference(x); - ref sbyte yRef = ref MemoryMarshal.GetReference(y); - ref sbyte dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, sbyte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] + y); - i++; - } - } - - protected override void Add(sbyte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (sbyte)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref sbyte xRef = ref MemoryMarshal.GetReference(x); - ref sbyte yRef = ref MemoryMarshal.GetReference(y); - ref sbyte dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, sbyte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] - y); - i++; - } - } - - protected override void Subtract(sbyte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (sbyte)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref sbyte xRef = ref MemoryMarshal.GetReference(x); - ref sbyte yRef = ref MemoryMarshal.GetReference(y); - ref sbyte dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, sbyte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] * y); - i++; - } - } - - protected override void Multiply(sbyte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (sbyte)(x * y[i]); - i++; - } - } - - protected override sbyte Divide(sbyte x, sbyte y) - { - return (sbyte)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref sbyte xRef = ref MemoryMarshal.GetReference(x); - ref sbyte yRef = ref MemoryMarshal.GetReference(y); - ref sbyte dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, sbyte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] / y); - i++; - } - } - - protected override void Divide(sbyte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (sbyte)(x / y[i]); - i++; - } - } - - protected override sbyte Modulo(sbyte x, sbyte y) - { - return (sbyte)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, sbyte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] % y); - i++; - } - } - - protected override void Modulo(sbyte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (sbyte)(x % y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] & y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, sbyte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] & y); - i++; - } - } - - protected override void And(sbyte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (sbyte)(x & y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] | y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, sbyte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] | y); - i++; - } - } - - protected override void Or(sbyte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (sbyte)(x | y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] ^ y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, sbyte y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (sbyte)(x[i] ^ y); - i++; - } - } - - protected override void Xor(sbyte x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (sbyte)(x ^ y[i]); - i++; - } - } - - protected override void LeftShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (sbyte)(x[i] << y); - } - - protected override void RightShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (sbyte)(x[i] >> y); - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, sbyte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, sbyte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, sbyte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, sbyte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, sbyte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, sbyte y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class ShortArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref short xRef = ref MemoryMarshal.GetReference(x); - ref short yRef = ref MemoryMarshal.GetReference(y); - ref short dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (short)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, short y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] + y); - i++; - } - } - - protected override void Add(short x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (short)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref short xRef = ref MemoryMarshal.GetReference(x); - ref short yRef = ref MemoryMarshal.GetReference(y); - ref short dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (short)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, short y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] - y); - i++; - } - } - - protected override void Subtract(short x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (short)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref short xRef = ref MemoryMarshal.GetReference(x); - ref short yRef = ref MemoryMarshal.GetReference(y); - ref short dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (short)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, short y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] * y); - i++; - } - } - - protected override void Multiply(short x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (short)(x * y[i]); - i++; - } - } - - protected override short Divide(short x, short y) - { - return (short)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref short xRef = ref MemoryMarshal.GetReference(x); - ref short yRef = ref MemoryMarshal.GetReference(y); - ref short dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (short)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, short y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] / y); - i++; - } - } - - protected override void Divide(short x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (short)(x / y[i]); - i++; - } - } - - protected override short Modulo(short x, short y) - { - return (short)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, short y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] % y); - i++; - } - } - - protected override void Modulo(short x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (short)(x % y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] & y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, short y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] & y); - i++; - } - } - - protected override void And(short x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (short)(x & y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] | y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, short y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] | y); - i++; - } - } - - protected override void Or(short x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (short)(x | y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] ^ y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, short y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (short)(x[i] ^ y); - i++; - } - } - - protected override void Xor(short x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (short)(x ^ y[i]); - i++; - } - } - - protected override void LeftShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (short)(x[i] << y); - } - - protected override void RightShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (short)(x[i] >> y); - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, short y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, short y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, short y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, short y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, short y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, short y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class UIntArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref uint xRef = ref MemoryMarshal.GetReference(x); - ref uint yRef = ref MemoryMarshal.GetReference(y); - ref uint dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (uint)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, uint y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] + y); - i++; - } - } - - protected override void Add(uint x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (uint)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref uint xRef = ref MemoryMarshal.GetReference(x); - ref uint yRef = ref MemoryMarshal.GetReference(y); - ref uint dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (uint)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, uint y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] - y); - i++; - } - } - - protected override void Subtract(uint x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (uint)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref uint xRef = ref MemoryMarshal.GetReference(x); - ref uint yRef = ref MemoryMarshal.GetReference(y); - ref uint dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (uint)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, uint y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] * y); - i++; - } - } - - protected override void Multiply(uint x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (uint)(x * y[i]); - i++; - } - } - - protected override uint Divide(uint x, uint y) - { - return (uint)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref uint xRef = ref MemoryMarshal.GetReference(x); - ref uint yRef = ref MemoryMarshal.GetReference(y); - ref uint dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (uint)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, uint y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] / y); - i++; - } - } - - protected override void Divide(uint x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (uint)(x / y[i]); - i++; - } - } - - protected override uint Modulo(uint x, uint y) - { - return (uint)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, uint y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] % y); - i++; - } - } - - protected override void Modulo(uint x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (uint)(x % y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] & y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, uint y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] & y); - i++; - } - } - - protected override void And(uint x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (uint)(x & y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] | y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, uint y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] | y); - i++; - } - } - - protected override void Or(uint x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (uint)(x | y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] ^ y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, uint y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (uint)(x[i] ^ y); - i++; - } - } - - protected override void Xor(uint x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (uint)(x ^ y[i]); - i++; - } - } - - protected override void LeftShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (uint)(x[i] << y); - } - - protected override void RightShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (uint)(x[i] >> y); - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, uint y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, uint y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, uint y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, uint y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, uint y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, uint y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class ULongArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref ulong xRef = ref MemoryMarshal.GetReference(x); - ref ulong yRef = ref MemoryMarshal.GetReference(y); - ref ulong dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, ulong y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] + y); - i++; - } - } - - protected override void Add(ulong x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ulong)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref ulong xRef = ref MemoryMarshal.GetReference(x); - ref ulong yRef = ref MemoryMarshal.GetReference(y); - ref ulong dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ulong y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] - y); - i++; - } - } - - protected override void Subtract(ulong x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ulong)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref ulong xRef = ref MemoryMarshal.GetReference(x); - ref ulong yRef = ref MemoryMarshal.GetReference(y); - ref ulong dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ulong y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] * y); - i++; - } - } - - protected override void Multiply(ulong x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ulong)(x * y[i]); - i++; - } - } - - protected override ulong Divide(ulong x, ulong y) - { - return (ulong)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref ulong xRef = ref MemoryMarshal.GetReference(x); - ref ulong yRef = ref MemoryMarshal.GetReference(y); - ref ulong dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, ulong y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] / y); - i++; - } - } - - protected override void Divide(ulong x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ulong)(x / y[i]); - i++; - } - } - - protected override ulong Modulo(ulong x, ulong y) - { - return (ulong)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, ulong y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] % y); - i++; - } - } - - protected override void Modulo(ulong x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ulong)(x % y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] & y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, ulong y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] & y); - i++; - } - } - - protected override void And(ulong x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ulong)(x & y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] | y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ulong y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] | y); - i++; - } - } - - protected override void Or(ulong x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ulong)(x | y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] ^ y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ulong y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ulong)(x[i] ^ y); - i++; - } - } - - protected override void Xor(ulong x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ulong)(x ^ y[i]); - i++; - } - } - - protected override void LeftShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (ulong)(x[i] << y); - } - - protected override void RightShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (ulong)(x[i] >> y); - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ulong y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ulong y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ulong y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ulong y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ulong y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ulong y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class UShortArithmetic : Arithmetic - { - - protected override void Add(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref ushort xRef = ref MemoryMarshal.GetReference(x); - ref ushort yRef = ref MemoryMarshal.GetReference(y); - ref ushort dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) + Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] + y[i]); - i++; - } - } - - protected override void Add(ReadOnlySpan x, ushort y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] + y); - i++; - } - } - - protected override void Add(ushort x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ushort)(x + y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref ushort xRef = ref MemoryMarshal.GetReference(x); - ref ushort yRef = ref MemoryMarshal.GetReference(y); - ref ushort dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) - Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] - y[i]); - i++; - } - } - - protected override void Subtract(ReadOnlySpan x, ushort y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] - y); - i++; - } - } - - protected override void Subtract(ushort x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ushort)(x - y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref ushort xRef = ref MemoryMarshal.GetReference(x); - ref ushort yRef = ref MemoryMarshal.GetReference(y); - ref ushort dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) * Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] * y[i]); - i++; - } - } - - protected override void Multiply(ReadOnlySpan x, ushort y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] * y); - i++; - } - } - - protected override void Multiply(ushort x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ushort)(x * y[i]); - i++; - } - } - - protected override ushort Divide(ushort x, ushort y) - { - return (ushort)(x / y); - } - - protected override void Divide(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - if (Vector.IsHardwareAccelerated) - { - ref ushort xRef = ref MemoryMarshal.GetReference(x); - ref ushort yRef = ref MemoryMarshal.GetReference(y); - ref ushort dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) / Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] / y[i]); - i++; - } - } - - protected override void Divide(ReadOnlySpan x, ushort y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] / y); - i++; - } - } - - protected override void Divide(ushort x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ushort)(x / y[i]); - i++; - } - } - - protected override ushort Modulo(ushort x, ushort y) - { - return (ushort)(x % y); - } - - protected override void Modulo(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] % y[i]); - i++; - } - } - - protected override void Modulo(ReadOnlySpan x, ushort y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] % y); - i++; - } - } - - protected override void Modulo(ushort x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ushort)(x % y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] & y[i]); - i++; - } - } - - protected override void And(ReadOnlySpan x, ushort y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] & y); - i++; - } - } - - protected override void And(ushort x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ushort)(x & y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] | y[i]); - i++; - } - } - - protected override void Or(ReadOnlySpan x, ushort y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] | y); - i++; - } - } - - protected override void Or(ushort x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ushort)(x | y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] ^ y[i]); - i++; - } - } - - protected override void Xor(ReadOnlySpan x, ushort y, Span destination) - { - int i = 0; - - while (i < x.Length) - { - destination[i] = (ushort)(x[i] ^ y); - i++; - } - } - - protected override void Xor(ushort x, ReadOnlySpan y, Span destination) - { - int i = 0; - - while (i < y.Length) - { - destination[i] = (ushort)(x ^ y[i]); - i++; - } - } - - protected override void LeftShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (ushort)(x[i] << y); - } - - protected override void RightShift(ReadOnlySpan x, int y, Span destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (ushort)(x[i] >> y); - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, ushort y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ushort y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y[i]); - } - } - - protected override void ElementwiseGreaterThanOrEqual(ReadOnlySpan x, ushort y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] >= y); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y[i]); - } - } - - protected override void ElementwiseLessThanOrEqual(ReadOnlySpan x, ushort y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <= y); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y[i]); - } - } - - protected override void ElementwiseGreaterThan(ReadOnlySpan x, ushort y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] > y); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y[i]); - } - } - - protected override void ElementwiseLessThan(ReadOnlySpan x, ushort y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] < y); - } - } - } - internal class DateTimeArithmetic : Arithmetic - { - - protected override void ElementwiseEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y[i]); - } - } - - protected override void ElementwiseEquals(ReadOnlySpan x, DateTime y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] == y); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, ReadOnlySpan y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y[i]); - } - } - - protected override void ElementwiseNotEquals(ReadOnlySpan x, DateTime y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] != y); - } - } - } -} diff --git a/src/Microsoft.Data.Analysis/Computations/Arithmetics.tt b/src/Microsoft.Data.Analysis/Computations/Arithmetics.tt deleted file mode 100644 index 7971b09de..000000000 --- a/src/Microsoft.Data.Analysis/Computations/Arithmetics.tt +++ /dev/null @@ -1,171 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ output extension=".cs" #> -<#@ include file="$(ProjectDir)\ColumnArithmeticTemplate.ttinclude" #> -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Generated from Arithmetics.tt. Do not modify directly - -using System; -using System.Numerics; -using System.Runtime.InteropServices; - -namespace Microsoft.Data.Analysis -{ -<# foreach (TypeConfiguration type in typeConfiguration) { #> - internal class <#=type.ClassPrefix#>Arithmetic : Arithmetic<<#=type.TypeName#>> - { -<# foreach (MethodConfiguration method in methodConfiguration) { #> -<# if (!((method.IsNumeric && !type.SupportsNumeric) || (method.IsBitwise && !type.SupportsBitwise) || (type.UnsupportedMethods.Contains(method.MethodName))) && method.Operator != null) { #> -<# if (method.MethodType == MethodType.Comparison) { #> - - protected override void <#=method.MethodName#>(ReadOnlySpan<<#=type.TypeName#>> x, ReadOnlySpan<<#=type.TypeName#>> y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <#= method.Operator #> y[i]); - } - } -<# } else if (method.MethodType == MethodType.ComparisonScalar) {#> - - protected override void <#=method.MethodName#>(ReadOnlySpan<<#=type.TypeName#>> x, <#=type.TypeName#> y, Span destination) - { - for (var i = 0; i < x.Length; i++) - { - destination[i] = (x[i] <#= method.Operator #> y); - } - } -<# } else if (method.MethodType == MethodType.Binary) { #> -<# if (method.MethodName == "Divide" || method.MethodName == "Modulo") { #> - - protected override <#=type.TypeName#> <#=method.MethodName#>(<#=type.TypeName#> x, <#=type.TypeName#> y) - { - return (<#=type.TypeName#>)(x <#= method.Operator #> y); - } -<# } #> - - protected override void <#=method.MethodName#>(ReadOnlySpan<<#=type.TypeName#>> x, ReadOnlySpan<<#=type.TypeName#>> y, Span<<#=type.TypeName#>> destination) - { - int i = 0; -<# if (method.SupportsVectorization && type.SupportsVectorization) { #> - if (Vector.IsHardwareAccelerated) - { - ref <#=type.TypeName#> xRef = ref MemoryMarshal.GetReference(x); - ref <#=type.TypeName#> yRef = ref MemoryMarshal.GetReference(y); - ref <#=type.TypeName#> dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector<<#=type.TypeName#>>.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) <#= method.Operator #> Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } -<# } #> - - while (i < x.Length) - { - destination[i] = (<#=type.TypeName#>)(x[i] <#= method.Operator #> y[i]); - i++; - } - } -<# } #> -<# else if (method.MethodType == MethodType.BinaryScalar) { #> - - protected override void <#=method.MethodName#>(ReadOnlySpan<<#=type.TypeName#>> x, <#=type.TypeName#> y, Span<<#=type.TypeName#>> destination) - { - int i = 0; -<# if (method.SupportsVectorization && type.SupportsVectorization) { #> - if (Vector.IsHardwareAccelerated) - { - ref <#=type.TypeName#> xRef = ref MemoryMarshal.GetReference(x); - ref <#=type.TypeName#> dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector<<#=type.TypeName#>>.Count; - var oneVectorFromEnd = x.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - Vector<<#=type.TypeName#>> yVec = new(y); - - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (Arithmetic.AsVector(ref xRef, i) <#= method.Operator #> yVec); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } -<# } #> - - while (i < x.Length) - { - destination[i] = (<#=type.TypeName#>)(x[i] <#= method.Operator #> y); - i++; - } - } - - protected override void <#=method.MethodName#>(<#=type.TypeName#> x, ReadOnlySpan<<#=type.TypeName#>> y, Span<<#=type.TypeName#>> destination) - { - int i = 0; -<# if (method.SupportsVectorization && type.SupportsVectorization) { #> - if (Vector.IsHardwareAccelerated) - { - ref <#=type.TypeName#> yRef = ref MemoryMarshal.GetReference(y); - ref <#=type.TypeName#> dRef = ref MemoryMarshal.GetReference(destination); - - var vectorSize = Vector<<#=type.TypeName#>>.Count; - var oneVectorFromEnd = y.Length - vectorSize; - - if (oneVectorFromEnd >= 0) - { - Vector<<#=type.TypeName#>> xVec = new(x); - - // Loop handling one vector at a time. - do - { - Arithmetic.AsVector(ref dRef, i) = (xVec <#= method.Operator #> Arithmetic.AsVector(ref yRef, i)); - - i += vectorSize; - } - while (i <= oneVectorFromEnd); - } - } -<# } #> - - while (i < y.Length) - { - destination[i] = (<#=type.TypeName#>)(x <#= method.Operator #> y[i]); - i++; - } - } -<# } #> -<# else if (method.MethodType == MethodType.BinaryInt) { #> - - protected override void <#=method.MethodName#>(ReadOnlySpan<<#=type.TypeName#>> x, int y, Span<<#=type.TypeName#>> destination) - { - for (var i = 0; i < x.Length; i++) - destination[i] = (<#=type.TypeName#>)(x[i] <#= method.Operator #> y); - } -<# } #> -<# } #> -<# } #> - } -<# } #> -} diff --git a/src/Microsoft.Data.Analysis/Microsoft.Data.Analysis.csproj b/src/Microsoft.Data.Analysis/Microsoft.Data.Analysis.csproj index d80a7b654..aeaea39c3 100644 --- a/src/Microsoft.Data.Analysis/Microsoft.Data.Analysis.csproj +++ b/src/Microsoft.Data.Analysis/Microsoft.Data.Analysis.csproj @@ -44,6 +44,10 @@ PrimitiveDataFrameColumn.BinaryOperators.tt + + + + @@ -64,9 +68,9 @@ TextTemplatingFileGenerator ColumnArithmetic.OperationEnums.cs - + TextTemplatingFileGenerator - Arithmetic.cs + Arithmetic.netstandard.cs TextTemplatingFileGenerator @@ -125,18 +129,10 @@ TextTemplatingFileGenerator PrimitiveDataFrameColumn.Computations.cs - - TextTemplatingFileGenerator - PrimitiveColumnArithmetic.cs - TextTemplatingFileGenerator PrimitiveDataFrameColumnComputations.cs - - TextTemplatingFileGenerator - Arithmetics.cs - @@ -144,10 +140,10 @@ - + True True - Arithmetic.tt + Arithmetic.netstandard.tt True @@ -214,21 +210,11 @@ True PrimitiveDataFrameColumn.Computations.tt - - True - True - PrimitiveColumnArithmetic.tt - True True PrimitiveDataFrameColumnComputations.tt - - True - True - Arithmetics.tt - True True diff --git a/test/Microsoft.Data.Analysis.Tests/DataFrameTests.BinaryOperations.cs b/test/Microsoft.Data.Analysis.Tests/DataFrameTests.BinaryOperations.cs index c077bd201..752a6f0f6 100644 --- a/test/Microsoft.Data.Analysis.Tests/DataFrameTests.BinaryOperations.cs +++ b/test/Microsoft.Data.Analysis.Tests/DataFrameTests.BinaryOperations.cs @@ -24,30 +24,39 @@ namespace Microsoft.Data.Analysis.Tests var ret = df.Add(5); Assert.Equal(0, df[0, 0]); Assert.Equal(5, ret[0, 0]); + ret = df.Add(listOfInts); Assert.Equal(0, df[0, 0]); Assert.Equal(5, ret[0, 0]); + ret = df.Subtract(5); Assert.Equal(0, df[0, 0]); Assert.Equal(-5, ret[0, 0]); + ret = df.Subtract(listOfInts); Assert.Equal(0, df[0, 0]); Assert.Equal(-5, ret[0, 0]); + ret = df.Multiply(5); Assert.Equal(1, df[1, 0]); Assert.Equal(5, ret[1, 0]); + ret = df.Multiply(listOfInts); Assert.Equal(1, df[1, 0]); Assert.Equal(5, ret[1, 0]); + ret = df.Divide(5); Assert.Equal(5, df[5, 0]); Assert.Equal(1, ret[5, 0]); + ret = df.Divide(listOfInts); Assert.Equal(5, df[5, 0]); Assert.Equal(1, ret[5, 0]); + ret = df.Modulo(5); Assert.Equal(5, df[5, 0]); Assert.Equal(0, ret[5, 0]); + ret = df.Modulo(listOfInts); Assert.Equal(5, df[5, 0]); Assert.Equal(0, ret[5, 0]);