diff --git a/docs/project/list-of-diagnostics.md b/docs/project/list-of-diagnostics.md index e203738bcac936..0b3da600c53b13 100644 --- a/docs/project/list-of-diagnostics.md +++ b/docs/project/list-of-diagnostics.md @@ -310,9 +310,9 @@ Diagnostic id values for experimental APIs must not be recycled, as that could s | Diagnostic ID | Introduced | Removed | Description | | :---------------- | ---------: | ------: | :---------- | -| __`SYSLIB5001`__ | .NET 9 | TBD | `Tensor` and related APIs in System.Numerics.Tensors are experimental | +| __`SYSLIB5001`__ | .NET 9 | .NET 10 | `Tensor` and related APIs in System.Numerics.Tensors are experimental | | __`SYSLIB5002`__ | .NET 9 | TBD | `SystemColors` alternate colors are experimental | | __`SYSLIB5003`__ | .NET 9 | TBD | `System.Runtime.Intrinsics.Arm.Sve` is experimental | | __`SYSLIB5004`__ | .NET 9 | TBD | `X86Base.DivRem` is experimental since performance is not as optimized as `T.DivRem` | -| __`SYSLIB5005`__ | .NET 9 | TBD | `System.Formats.Nrbf` is experimental | +| __`SYSLIB5005`__ | .NET 9 | .NET 10 | `System.Formats.Nrbf` is experimental | | __`SYSLIB5006`__ | .NET 10 | TBD | Types for Post-Quantum Cryptography (PQC) are experimental. | diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj index 3f78270ba33f08..d177b32ecb44a7 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj @@ -3,8 +3,8 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true - - $(NoWarn);SYSLIB5001 + + $(NoWarn);SA1001 diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.net9.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.net9.cs index 74f068d61918d3..e3e27003e11f91 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.net9.cs +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.net9.cs @@ -19,6 +19,16 @@ public readonly ref partial struct ReadOnlyTensorDimensionSpan void System.IDisposable.Dispose() { } } } + public readonly ref partial struct ReadOnlyTensorSpan : System.Numerics.Tensors.IReadOnlyTensor, System.Numerics.Tensors.IReadOnlyTensor, T> + { + object? System.Numerics.Tensors.IReadOnlyTensor.this[params scoped System.ReadOnlySpan indexes] { get { throw null; } } + object? System.Numerics.Tensors.IReadOnlyTensor.this[params scoped System.ReadOnlySpan indexes] { get { throw null; } } + System.Numerics.Tensors.ReadOnlyTensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.AsReadOnlyTensorSpan() { throw null; } + System.Numerics.Tensors.ReadOnlyTensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.AsReadOnlyTensorSpan(params scoped System.ReadOnlySpan startIndexes) { throw null; } + System.Numerics.Tensors.ReadOnlyTensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.AsReadOnlyTensorSpan(params scoped System.ReadOnlySpan startIndexes) { throw null; } + System.Numerics.Tensors.ReadOnlyTensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.AsReadOnlyTensorSpan(params scoped System.ReadOnlySpan ranges) { throw null; } + System.Numerics.Tensors.ReadOnlyTensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.ToDenseTensor() { throw null; } + } public readonly ref partial struct TensorDimensionSpan { public ref partial struct Enumerator : System.Collections.Generic.IEnumerator>, System.Collections.IEnumerator, System.IDisposable @@ -27,4 +37,31 @@ public readonly ref partial struct TensorDimensionSpan void System.IDisposable.Dispose() { } } } + public readonly ref partial struct TensorSpan : System.Numerics.Tensors.IReadOnlyTensor, System.Numerics.Tensors.IReadOnlyTensor, T>, System.Numerics.Tensors.ITensor, System.Numerics.Tensors.ITensor, T> + { + object? System.Numerics.Tensors.IReadOnlyTensor.this[params scoped System.ReadOnlySpan indexes] { get { throw null; } } + object? System.Numerics.Tensors.IReadOnlyTensor.this[params scoped System.ReadOnlySpan indexes] { get { throw null; } } + ref readonly T System.Numerics.Tensors.IReadOnlyTensor, T>.this[params scoped System.ReadOnlySpan indexes] { get { throw null; } } + ref readonly T System.Numerics.Tensors.IReadOnlyTensor, T>.this[params scoped System.ReadOnlySpan indexes] { get { throw null; } } + System.Numerics.Tensors.ReadOnlyTensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.AsReadOnlyTensorSpan() { throw null; } + System.Numerics.Tensors.ReadOnlyTensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.AsReadOnlyTensorSpan(params scoped System.ReadOnlySpan startIndexes) { throw null; } + System.Numerics.Tensors.ReadOnlyTensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.AsReadOnlyTensorSpan(params scoped System.ReadOnlySpan startIndexes) { throw null; } + System.Numerics.Tensors.ReadOnlyTensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.AsReadOnlyTensorSpan(params scoped System.ReadOnlySpan ranges) { throw null; } + System.Numerics.Tensors.ReadOnlyTensorDimensionSpan System.Numerics.Tensors.IReadOnlyTensor, T>.GetDimensionSpan(int dimension) { throw null; } + ref readonly T System.Numerics.Tensors.IReadOnlyTensor, T>.GetPinnableReference() { throw null; } + System.Numerics.Tensors.TensorSpan System.Numerics.Tensors.IReadOnlyTensor, T>.ToDenseTensor() { throw null; } + + bool System.Numerics.Tensors.ITensor.IsReadOnly { get { throw null; } } + object? System.Numerics.Tensors.ITensor.this[params scoped System.ReadOnlySpan indexes] { get { throw null; } set { } } + object? System.Numerics.Tensors.ITensor.this[params scoped System.ReadOnlySpan indexes] { get { throw null; } set { } } + void System.Numerics.Tensors.ITensor.Fill(object value) { } + static System.Numerics.Tensors.TensorSpan ITensor, T>.Create(scoped System.ReadOnlySpan lengths, bool pinned) { throw null; } + static System.Numerics.Tensors.TensorSpan ITensor, T>.Create(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } + static System.Numerics.Tensors.TensorSpan ITensor, T>.CreateUninitialized(scoped System.ReadOnlySpan lengths, bool pinned) { throw null; } + static System.Numerics.Tensors.TensorSpan ITensor, T>.CreateUninitialized(scoped System.ReadOnlySpan lengths, scoped System.ReadOnlySpan strides, bool pinned) { throw null; } + System.Numerics.Tensors.TensorSpan System.Numerics.Tensors.ITensor, T>.AsTensorSpan() { throw null; } + System.Numerics.Tensors.TensorSpan System.Numerics.Tensors.ITensor, T>.AsTensorSpan(params scoped System.ReadOnlySpan startIndexes) { throw null; } + System.Numerics.Tensors.TensorSpan System.Numerics.Tensors.ITensor, T>.AsTensorSpan(params scoped System.ReadOnlySpan startIndexes) { throw null; } + System.Numerics.Tensors.TensorSpan System.Numerics.Tensors.ITensor, T>.AsTensorSpan(params scoped System.ReadOnlySpan ranges) { throw null; } + } } diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs index a91431b35fcf0e..6b7d71d600b55f 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs @@ -6,7 +6,6 @@ namespace System.Buffers { - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5001", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public readonly partial struct NIndex : System.IEquatable { private readonly int _dummyPrimitive; @@ -30,7 +29,6 @@ namespace System.Buffers public System.Index ToIndexUnchecked() { throw null; } public override string ToString() { throw null; } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5001", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public readonly partial struct NRange : System.IEquatable { private readonly int _dummyPrimitive; @@ -55,7 +53,6 @@ namespace System.Buffers } namespace System.Numerics.Tensors { - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5001", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public partial interface IReadOnlyTensor { nint FlattenedLength { get; } @@ -70,10 +67,12 @@ public partial interface IReadOnlyTensor int Rank { get; } [System.Diagnostics.CodeAnalysis.UnscopedRefAttribute] System.ReadOnlySpan Strides { get; } - System.Buffers.MemoryHandle GetPinnedHandle(); } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5001", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] - public partial interface IReadOnlyTensor : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable, System.Numerics.Tensors.IReadOnlyTensor where TSelf : System.Numerics.Tensors.IReadOnlyTensor + public partial interface IReadOnlyTensor : System.Numerics.Tensors.IReadOnlyTensor + where TSelf : System.Numerics.Tensors.IReadOnlyTensor +#if NET9_0_OR_GREATER + , allows ref struct +#endif { static abstract TSelf Empty { get; } new ref readonly T this[params scoped System.ReadOnlySpan indexes] { get; } @@ -94,7 +93,6 @@ public partial interface IReadOnlyTensor : System.Collections.Generic. bool TryCopyTo(scoped in System.Numerics.Tensors.TensorSpan destination); bool TryFlattenTo(scoped System.Span destination); } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5001", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public partial interface ITensor : System.Numerics.Tensors.IReadOnlyTensor { bool IsReadOnly { get; } @@ -103,8 +101,11 @@ public partial interface ITensor : System.Numerics.Tensors.IReadOnlyTensor void Clear(); void Fill(object value); } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5001", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] - public partial interface ITensor : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable, System.Numerics.Tensors.IReadOnlyTensor, System.Numerics.Tensors.IReadOnlyTensor, System.Numerics.Tensors.ITensor where TSelf : System.Numerics.Tensors.ITensor + public partial interface ITensor : System.Numerics.Tensors.IReadOnlyTensor, System.Numerics.Tensors.IReadOnlyTensor, System.Numerics.Tensors.ITensor + where TSelf : System.Numerics.Tensors.ITensor +#if NET9_0_OR_GREATER + , allows ref struct +#endif { new ref T this[params scoped System.ReadOnlySpan indexes] { get; } new TSelf this[params scoped System.ReadOnlySpan ranges] { get; set; } @@ -126,6 +127,7 @@ public readonly ref partial struct ReadOnlyTensorDimensionSpan private readonly object _dummy; private readonly int _dummyPrimitive; public System.Numerics.Tensors.ReadOnlyTensorSpan this[nint index] { get { throw null; } } + public bool IsDense { get { throw null; } } public nint Length { get { throw null; } } public System.Numerics.Tensors.ReadOnlyTensorDimensionSpan.Enumerator GetEnumerator() { throw null; } public ref partial struct Enumerator @@ -137,7 +139,6 @@ public ref partial struct Enumerator public void Reset() { } } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5001", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public readonly ref partial struct ReadOnlyTensorSpan { private readonly object _dummy; @@ -162,6 +163,7 @@ public readonly ref partial struct ReadOnlyTensorSpan public bool HasAnyDenseDimensions { get { throw null; } } public bool IsDense { get { throw null; } } public bool IsEmpty { get { throw null; } } + public bool IsPinned { get { throw null; } } public ref readonly T this[params scoped System.ReadOnlySpan indexes] { get { throw null; } } public System.Numerics.Tensors.ReadOnlyTensorSpan this[params scoped System.ReadOnlySpan ranges] { get { throw null; } } public ref readonly T this[params scoped System.ReadOnlySpan indexes] { get { throw null; } } @@ -205,10 +207,9 @@ public void FlattenTo(scoped System.Span destination) { } readonly object? System.Collections.IEnumerator.Current { get { throw null; } } public bool MoveNext() { throw null; } public void Reset() { } - void System.IDisposable.Dispose() { } + readonly void System.IDisposable.Dispose() { } } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5001", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static partial class Tensor { public static System.Numerics.Tensors.Tensor Abs(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.INumberBase { throw null; } @@ -578,7 +579,9 @@ public readonly ref partial struct TensorDimensionSpan private readonly object _dummy; private readonly int _dummyPrimitive; public System.Numerics.Tensors.TensorSpan this[nint index] { get { throw null; } } + public bool IsDense { get { throw null; } } public nint Length { get { throw null; } } + public static implicit operator System.Numerics.Tensors.ReadOnlyTensorDimensionSpan(scoped in System.Numerics.Tensors.TensorDimensionSpan tensorDimension) { throw null; } public System.Numerics.Tensors.TensorDimensionSpan.Enumerator GetEnumerator() { throw null; } public ref partial struct Enumerator { @@ -823,7 +826,6 @@ public static void Truncate(System.ReadOnlySpan x, System.Span destinat public static void Xor(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) where T : System.Numerics.IBitwiseOperators { } public static void Xor(System.ReadOnlySpan x, T y, System.Span destination) where T : System.Numerics.IBitwiseOperators { } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5001", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public readonly ref partial struct TensorSpan { private readonly object _dummy; @@ -848,6 +850,7 @@ public readonly ref partial struct TensorSpan public bool HasAnyDenseDimensions { get { throw null; } } public bool IsDense { get { throw null; } } public bool IsEmpty { get { throw null; } } + public bool IsPinned { get { throw null; } } public ref T this[params scoped System.ReadOnlySpan indexes] { get { throw null; } } public System.Numerics.Tensors.TensorSpan this[params scoped System.ReadOnlySpan ranges] { get { throw null; } set { } } public ref T this[params scoped System.ReadOnlySpan indexes] { get { throw null; } } @@ -897,11 +900,10 @@ public void FlattenTo(scoped System.Span destination) { } readonly object? System.Collections.IEnumerator.Current { get { throw null; } } public bool MoveNext() { throw null; } public void Reset() { } - void System.IDisposable.Dispose() { } + readonly void System.IDisposable.Dispose() { } } } - [System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5001", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] - public sealed partial class Tensor : System.Collections.Generic.IEnumerable, System.Collections.IEnumerable, System.Numerics.Tensors.IReadOnlyTensor, System.Numerics.Tensors.IReadOnlyTensor, T>, System.Numerics.Tensors.ITensor, System.Numerics.Tensors.ITensor, T> + public sealed partial class Tensor : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable, System.Numerics.Tensors.IReadOnlyTensor, System.Numerics.Tensors.IReadOnlyTensor, T>, System.Numerics.Tensors.ITensor, System.Numerics.Tensors.ITensor, T> { internal Tensor() { } public static System.Numerics.Tensors.Tensor Empty { get { throw null; } } diff --git a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml index 69a05a12b81567..13243a79731835 100644 --- a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml @@ -253,6 +253,146 @@ lib/net9.0/System.Numerics.Tensors.dll true + + CP0008 + T:System.Numerics.Tensors.IReadOnlyTensor`2 + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0008 + T:System.Numerics.Tensors.ITensor`2 + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0008 + T:System.Numerics.Tensors.IReadOnlyTensor`2 + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0008 + T:System.Numerics.Tensors.ITensor`2 + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Buffers.NIndex:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Buffers.NRange:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.IReadOnlyTensor`2:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.ITensor`2:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.ReadOnlyTensorSpan`1:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.Tensor:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.Tensor`1:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.TensorSpan`1:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Buffers.NIndex:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Buffers.NRange:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.IReadOnlyTensor`2:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.ITensor`2:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.ReadOnlyTensorSpan`1:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.Tensor:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.Tensor`1:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + + CP0014 + T:System.Numerics.Tensors.TensorSpan`1:[T:System.Diagnostics.CodeAnalysis.ExperimentalAttribute] + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + CP0017 M:System.Numerics.Tensors.IReadOnlyTensor`2.AsReadOnlyTensorSpan(System.ReadOnlySpan{System.Buffers.NIndex})$0 @@ -631,4 +771,4 @@ lib/net9.0/System.Numerics.Tensors.dll true - \ No newline at end of file + diff --git a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj index 5fa3946074f6d1..2fe51c32663c6b 100644 --- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj @@ -7,8 +7,8 @@ Provides support for operating over tensors. ReferenceAssemblyExclusions.txt $([MSBuild]::NormalizePath('$(MSBuildProjectDirectory)', '..', 'ref', '$(AssemblyName).netcore.cs')) - - $(NoWarn);SYSLIB5001 + + $(NoWarn);SA1001 @@ -16,7 +16,6 @@ - diff --git a/src/libraries/System.Numerics.Tensors/src/System/Buffers/NIndex.cs b/src/libraries/System.Numerics.Tensors/src/System/Buffers/NIndex.cs index e2d2cfef635187..a3e6a8947eb2c8 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Buffers/NIndex.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Buffers/NIndex.cs @@ -14,7 +14,6 @@ namespace System.Buffers /// int lastElement = someArray[^1]; // lastElement = 5 /// /// - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public readonly struct NIndex : IEquatable { private readonly nint _value; diff --git a/src/libraries/System.Numerics.Tensors/src/System/Buffers/NRange.cs b/src/libraries/System.Numerics.Tensors/src/System/Buffers/NRange.cs index 43e0ff9c565017..ad452f8385c4b8 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Buffers/NRange.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Buffers/NRange.cs @@ -15,7 +15,6 @@ namespace System.Buffers /// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 } /// /// - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public readonly struct NRange : IEquatable { /// Gets the inclusive start NIndex of the NRange. diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs index aba695b7bae89f..f93b26a658068f 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs @@ -7,7 +7,6 @@ namespace System.Numerics.Tensors { /// Represents a read-only tensor. - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public interface IReadOnlyTensor { /// Gets the specified element of the tensor. @@ -59,9 +58,5 @@ public interface IReadOnlyTensor /// Gets the stride of each dimension in the tensor. [UnscopedRef] ReadOnlySpan Strides { get; } - - /// Pins and gets a to the backing memory. - /// - MemoryHandle GetPinnedHandle(); } } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor_1.cs index 68365ee69a253e..1627d66c0c3720 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor_1.cs @@ -2,17 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; namespace System.Numerics.Tensors { /// Represents a read-only tensor. /// The type that implements this interface. /// The element type. - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] - public interface IReadOnlyTensor : IReadOnlyTensor, IEnumerable + public interface IReadOnlyTensor : IReadOnlyTensor where TSelf : IReadOnlyTensor +#if NET9_0_OR_GREATER + , allows ref struct +#endif { /// Gets an empty tensor. static abstract TSelf Empty { get; } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs index 9d8162e51ddb45..a64d32bfbd3da7 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs @@ -7,7 +7,6 @@ namespace System.Numerics.Tensors { /// Represents a tensor. - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public interface ITensor : IReadOnlyTensor { /// Gets or sets the specified element of the tensor. diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor_1.cs index c7b0ab8b1d60da..576cd6e4120646 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor_1.cs @@ -2,16 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; -using System.Diagnostics.CodeAnalysis; namespace System.Numerics.Tensors { /// Represents a tensor. /// The type that implements this interface. /// The element type. - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public interface ITensor : ITensor, IReadOnlyTensor where TSelf : ITensor +#if NET9_0_OR_GREATER + , allows ref struct +#endif { // TODO: Determine if we can implement `IEqualityOperators`. // It looks like C#/.NET currently hits limitations here as it believes TSelf and T could be the same type diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorDimensionSpan_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorDimensionSpan_1.cs index 32d3374acf459f..ffa05a45a85909 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorDimensionSpan_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorDimensionSpan_1.cs @@ -1,10 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.CompilerServices; + +#if NET9_0_OR_GREATER using System.Collections; using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; +#endif namespace System.Numerics.Tensors { @@ -28,9 +30,12 @@ internal ReadOnlyTensorDimensionSpan(ReadOnlyTensorSpan tensor, int dimension _tensor = tensor; _length = TensorPrimitives.Product(tensor.Lengths[..dimension]); _dimension = dimension; - _sliceShape = TensorShape.Create((dimension != tensor.Rank) ? tensor.Lengths[dimension..] : [1], tensor.Strides[dimension..]); + _sliceShape = TensorShape.Create((dimension != tensor.Rank) ? tensor.Lengths[dimension..] : [1], tensor.Strides[dimension..], tensor.IsPinned); } + /// Gets true if the slices that exist within the tracked dimension are dense; otherwise, false. + public bool IsDense => _sliceShape.IsDense; + /// Gets the length of the tensor dimension span. public nint Length => _length; diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan_1.cs index 74e6d6c0423517..30a3139b33cf56 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan_1.cs @@ -21,8 +21,10 @@ namespace System.Numerics.Tensors /// The type of the elements within the tensor span. [DebuggerTypeProxy(typeof(TensorSpanDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public readonly ref struct ReadOnlyTensorSpan +#if NET9_0_OR_GREATER + : IReadOnlyTensor, T> +#endif { /// public static ReadOnlyTensorSpan Empty => default; @@ -55,12 +57,7 @@ public ReadOnlyTensorSpan(T[]? array) /// * is not empty and has a flattened length greater than .Length. /// public ReadOnlyTensorSpan(T[]? array, scoped ReadOnlySpan lengths) - { - _shape = TensorShape.Create(array, lengths); - _reference = ref (array is not null) - ? ref MemoryMarshal.GetArrayDataReference(array) - : ref Unsafe.NullRef(); - } + : this(array, lengths, strides: []) { } /// Creates a new tensor over the portion of the target array beginning at the specified start index and using the specified lengths and strides. /// The target array. @@ -114,7 +111,7 @@ public ReadOnlyTensorSpan(T[]? array, int start, scoped ReadOnlySpan lengt public ReadOnlyTensorSpan(ReadOnlySpan span) { ref T reference = ref MemoryMarshal.GetReference(span); - _shape = TensorShape.Create(ref reference, span.Length); + _shape = TensorShape.Create(ref reference, span.Length, pinned: false); _reference = ref reference; } @@ -127,11 +124,7 @@ public ReadOnlyTensorSpan(ReadOnlySpan span) /// * is not empty and has a flattened length greater than .Length. /// public ReadOnlyTensorSpan(ReadOnlySpan span, scoped ReadOnlySpan lengths) - { - ref T reference = ref MemoryMarshal.GetReference(span); - _shape = TensorShape.Create(ref reference, span.Length, lengths); - _reference = ref reference; - } + : this(span, lengths, strides: []) { } /// Creates a new tensor span over the target span using the specified lengths and strides. /// The target span. @@ -148,7 +141,7 @@ public ReadOnlyTensorSpan(ReadOnlySpan span, scoped ReadOnlySpan length public ReadOnlyTensorSpan(ReadOnlySpan span, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) { ref T reference = ref MemoryMarshal.GetReference(span); - _shape = TensorShape.Create(ref reference, span.Length, lengths, strides); + _shape = TensorShape.Create(ref reference, span.Length, lengths, strides, pinned: false); _reference = ref reference; } @@ -220,10 +213,7 @@ public unsafe ReadOnlyTensorSpan(T* data, nint dataLength) /// [CLSCompliant(false)] public unsafe ReadOnlyTensorSpan(T* data, nint dataLength, scoped ReadOnlySpan lengths) - { - _shape = TensorShape.Create(data, dataLength, lengths); - _reference = ref Unsafe.AsRef(data); - } + : this(data, dataLength, lengths, strides: []) { } /// Creates a new tensor span over the target unmanaged buffer using the specified lengths and strides. /// The pointer to the start of the target unmanaged buffer. @@ -248,28 +238,9 @@ public unsafe ReadOnlyTensorSpan(T* data, nint dataLength, scoped ReadOnlySpan(data); } - // Constructor for internal use only. It is not safe to expose publicly. - internal ReadOnlyTensorSpan(ref T data, nint dataLength) - { - _shape = TensorShape.Create(ref data, dataLength); - _reference = ref data; - } - - internal ReadOnlyTensorSpan(ref T data, nint dataLength, scoped ReadOnlySpan lengths) - { - _shape = TensorShape.Create(ref data, dataLength, lengths); - _reference = ref data; - } - - internal ReadOnlyTensorSpan(ref T data, nint dataLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) + internal ReadOnlyTensorSpan(ref T data, nint dataLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) { - _shape = TensorShape.Create(ref data, dataLength, lengths, strides); - _reference = ref data; - } - - internal ReadOnlyTensorSpan(ref T data, nint dataLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, scoped ReadOnlySpan linearRankOrder) - { - _shape = TensorShape.Create(ref data, dataLength, lengths, strides, linearRankOrder); + _shape = TensorShape.Create(ref data, dataLength, lengths, strides, pinned); _reference = ref data; } @@ -309,6 +280,9 @@ public ReadOnlyTensorSpan this[params scoped ReadOnlySpan ranges] /// public bool IsEmpty => _shape.IsEmpty; + /// + public bool IsPinned => _shape.IsPinned; + /// [UnscopedRef] public ReadOnlySpan Lengths => _shape.Lengths; @@ -464,11 +438,47 @@ public bool TryFlattenTo(scoped Span destination) return false; } +#if NET9_0_OR_GREATER + // + // IReadOnlyTensor + // + + object? IReadOnlyTensor.this[params scoped ReadOnlySpan indexes] => this[indexes]; + + object? IReadOnlyTensor.this[params scoped ReadOnlySpan indexes] => this[indexes]; + + // + // IReadOnlyTensor + // + + ReadOnlyTensorSpan IReadOnlyTensor, T>.AsReadOnlyTensorSpan() => this; + + ReadOnlyTensorSpan IReadOnlyTensor, T>.AsReadOnlyTensorSpan(params scoped ReadOnlySpan startIndexes) => Slice(startIndexes); + + ReadOnlyTensorSpan IReadOnlyTensor, T>.AsReadOnlyTensorSpan(params scoped ReadOnlySpan startIndexes) => Slice(startIndexes); + + ReadOnlyTensorSpan IReadOnlyTensor, T>.AsReadOnlyTensorSpan(params scoped ReadOnlySpan ranges) => Slice(ranges); + + ReadOnlyTensorSpan IReadOnlyTensor, T>.ToDenseTensor() + { + ReadOnlyTensorSpan result = this; + + if (!IsDense) + { + Tensor tmp = Tensor.Create(Lengths, IsPinned); + CopyTo(tmp); + result = tmp; + } + + return result; + } +#endif + /// Enumerates the elements of a tensor span. public ref struct Enumerator : IEnumerator { private readonly ReadOnlyTensorSpan _span; - private nint[] _indexes; + private readonly nint[] _indexes; private nint _linearOffset; private nint _itemsEnumerated; @@ -514,7 +524,7 @@ public void Reset() // IDisposable // - void IDisposable.Dispose() { } + readonly void IDisposable.Dispose() { } // // IEnumerator diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs index 7c8aec0244ebe7..2317c6933033ae 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.cs @@ -1,11 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Buffers; using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -14,7 +12,6 @@ namespace System.Numerics.Tensors { /// Provides methods for tensor operations. - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public static partial class Tensor { #region AsTensorSpan @@ -70,8 +67,8 @@ public static Tensor Broadcast(scoped in ReadOnlyTensorSpan source, sco /// The shapes are not broadcast compatible. public static Tensor Broadcast(scoped in ReadOnlyTensorSpan source, scoped ReadOnlySpan lengths) { - TensorOperation.ValidateCompatibility(source, lengths); - Tensor destination = Tensor.CreateUninitialized(lengths); + TensorOperation.ValidateCompatibility(source, lengths); + Tensor destination = CreateUninitialized(lengths); TensorOperation.Invoke, T, T>(source, destination); return destination; } @@ -107,7 +104,7 @@ public static void BroadcastTo(in this TensorSpan source, in TensorSpan /// public static void BroadcastTo(in this ReadOnlyTensorSpan source, in TensorSpan destination) { - TensorOperation.ValidateCompatibility(source, destination); + TensorOperation.ValidateCompatibility(source, destination); TensorOperation.Invoke, T, T>(source, destination); } #endregion @@ -162,7 +159,7 @@ public static Tensor ConcatenateOnDimension(int dimension, params scoped R nint[] lengths = new nint[tensors[0].Rank]; tensors[0].Lengths.CopyTo(lengths); lengths[dimension] = sumOfAxis; - tensor = Tensor.Create(lengths); + tensor = Create(lengths); } else { @@ -176,7 +173,7 @@ public static Tensor ConcatenateOnDimension(int dimension, params scoped R } } - tensor = Tensor.Create([totalLength]); + tensor = Create([totalLength]); } ConcatenateOnDimension(dimension, tensors, tensor); @@ -243,7 +240,7 @@ public static ref readonly TensorSpan ConcatenateOnDimension(int dimension } Span dstSpan = MemoryMarshal.CreateSpan(ref destination._reference, (int)totalLength); - if (dimension == 0 || dimension == -1) + if (dimension is 0 or -1) { for (int i = 0; i < tensors.Length; i++) { @@ -313,7 +310,7 @@ public static Tensor Create(T[] array) /// /// A new tensor that uses as its backing buffer and with the specified . public static Tensor Create(T[] array, scoped ReadOnlySpan lengths) - => new Tensor(array, lengths); + => new Tensor(array, lengths, strides: []); /// /// A new tensor that uses as its backing buffer and with the specified and . @@ -328,7 +325,7 @@ public static Tensor Create(T[] array, int start, scoped ReadOnlySpanA new tensor that contains elements copied from . public static Tensor Create(IEnumerable enumerable, bool pinned = false) { - T[] array = enumerable.ToArray(); + T[] array = [.. enumerable]; if (pinned) { @@ -352,7 +349,7 @@ public static Tensor Create(IEnumerable enumerable, scoped ReadOnlySpan /// A new tensor that contains elements copied from and with the specified and . public static Tensor Create(IEnumerable enumerable, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false) { - T[] array = enumerable.ToArray(); + T[] array = [.. enumerable]; if (pinned) { @@ -416,33 +413,29 @@ public static Tensor CreateAndFillUniformDistribution(Random random, scope /// public static Tensor CreateUninitialized(scoped ReadOnlySpan lengths, bool pinned = false) - { - TensorShape shape = TensorShape.Create(lengths, strides: []); - T[] array = GC.AllocateUninitializedArray(checked((int)(shape.LinearLength)), pinned); - return new Tensor(array, in shape, pinned); - } + => CreateUninitialized(lengths, strides: [], pinned); /// public static Tensor CreateUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false) { - TensorShape shape = TensorShape.Create(lengths, strides); + TensorShape shape = TensorShape.Create(lengths, strides, pinned); T[] values = GC.AllocateUninitializedArray(checked((int)(shape.LinearLength)), pinned); - return new Tensor(values, in shape, pinned); + return new Tensor(values, in shape); } #endregion #region Fill /// - /// Fills the given with random data in a Gaussian normal distribution. + /// Fills the given with random data in a Gaussian normal distribution. /// can optionally be provided for seeding. /// /// The element type. /// The destination where the data will be stored. - /// to provide random seeding. Defaults to if not provided. + /// to provide random seeding. Defaults to if not provided. /// public static ref readonly TensorSpan FillGaussianNormalDistribution(in TensorSpan destination, Random? random = null) where T : IFloatingPoint { - Span span = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape.LinearLength); + Span span = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape.LinearLength); random ??= Random.Shared; for (int i = 0; i < span.Length; i++) @@ -456,16 +449,16 @@ public static ref readonly TensorSpan FillGaussianNormalDistribution(in Te } /// - /// Fills the given with random data in a uniform distribution. + /// Fills the given with random data in a uniform distribution. /// can optionally be provided for seeding. /// /// The element type. /// The destination where the data will be stored. - /// to provide random seeding. Defaults to if not provided. + /// to provide random seeding. Defaults to if not provided. /// public static ref readonly TensorSpan FillUniformDistribution(in TensorSpan destination, Random? random = null) where T : IFloatingPoint { - Span span = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape.LinearLength); + Span span = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape.LinearLength); random ??= Random.Shared; for (int i = 0; i < span.Length; i++) span[i] = T.CreateChecked(random.NextDouble()); @@ -677,7 +670,7 @@ public static ref readonly TensorSpan GreaterThan(scoped in ReadOnlyTen public static Tensor GreaterThan(in ReadOnlyTensorSpan x, T y) where T : IComparisonOperators { - Tensor destination = Tensor.Create(x.Lengths, false); + Tensor destination = Create(x.Lengths, false); GreaterThan(x, y, destination); return destination; } @@ -858,7 +851,7 @@ public static ref readonly TensorSpan GreaterThanOrEqual(scoped in Read public static Tensor GreaterThanOrEqual(in ReadOnlyTensorSpan x, T y) where T : IComparisonOperators { - Tensor destination = Tensor.Create(x.Lengths, false); + Tensor destination = Create(x.Lengths, false); GreaterThanOrEqual(x, y, destination); return destination; } @@ -1039,7 +1032,7 @@ public static ref readonly TensorSpan LessThan(scoped in ReadOnlyTensor public static Tensor LessThan(in ReadOnlyTensorSpan x, T y) where T : IComparisonOperators { - Tensor destination = Tensor.Create(x.Lengths, false); + Tensor destination = Create(x.Lengths, false); LessThan(x, y, destination); return destination; } @@ -1220,7 +1213,7 @@ public static ref readonly TensorSpan LessThanOrEqual(scoped in ReadOnl public static Tensor LessThanOrEqual(in ReadOnlyTensorSpan x, T y) where T : IComparisonOperators { - Tensor destination = Tensor.Create(x.Lengths, false); + Tensor destination = Create(x.Lengths, false); LessThanOrEqual(x, y, destination); return destination; } @@ -1373,7 +1366,6 @@ public static Tensor PermuteDimensions(this Tensor tensor, ReadOnlySpan scoped Span newLengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer lengthsRentedBuffer); scoped Span newStrides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer stridesRentedBuffer); - scoped Span newLinearOrder = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer linearOrderRentedBuffer); Tensor outTensor; @@ -1383,7 +1375,6 @@ public static Tensor PermuteDimensions(this Tensor tensor, ReadOnlySpan { newLengths[i] = tensor.Lengths[tensor.Rank - 1 - i]; newStrides[i] = tensor.Strides[tensor.Rank - 1 - i]; - newLinearOrder[i] = tensor._shape.LinearRankOrder[tensor.Rank - 1 - i]; } } else @@ -1396,14 +1387,12 @@ public static Tensor PermuteDimensions(this Tensor tensor, ReadOnlySpan } newLengths[i] = tensor.Lengths[dimensions[i]]; newStrides[i] = tensor.Strides[dimensions[i]]; - newLinearOrder[i] = tensor._shape.LinearRankOrder[dimensions[i]]; } } - outTensor = new Tensor(tensor._values, tensor._start, newLengths, newStrides, newLinearOrder); + outTensor = new Tensor(tensor._values, tensor._start, newLengths, newStrides); lengthsRentedBuffer.Dispose(); stridesRentedBuffer.Dispose(); - linearOrderRentedBuffer.Dispose(); return outTensor; } @@ -1428,7 +1417,7 @@ public static Tensor Reshape(this Tensor tensor, ReadOnlySpan len ThrowHelper.ThrowArgument_CannotReshapeNonContiguousOrDense(); } - nint[] newLengths = lengths.ToArray(); + nint[] newLengths = [.. lengths]; // Calculate wildcard info. int wildcardIndex = lengths.IndexOf(-1); if (wildcardIndex >= 0) @@ -1460,7 +1449,7 @@ public static Tensor Reshape(this Tensor tensor, ReadOnlySpan len // If we contain a 0 stride we can only add dimensions of length 1. else if (tensor.Strides.Contains(0)) { - List origStrides = new List(tensor.Strides.ToArray()); + List origStrides = [.. tensor.Strides]; int lengthOffset = 0; for (int i = 0; i < newLengths.Length; i++) { @@ -1476,7 +1465,7 @@ public static Tensor Reshape(this Tensor tensor, ReadOnlySpan len else ThrowHelper.ThrowArgument_InvalidReshapeDimensions(); } - strides = origStrides.ToArray(); + strides = [.. origStrides]; } else strides = []; @@ -1501,7 +1490,7 @@ public static TensorSpan Reshape(this scoped in TensorSpan tensor, scop ThrowHelper.ThrowArgument_CannotReshapeNonContiguousOrDense(); } - nint[] newLengths = lengths.ToArray(); + nint[] newLengths = [.. lengths]; int wildcardIndex = lengths.IndexOf(-1); if (wildcardIndex >= 0) { @@ -1533,7 +1522,7 @@ public static TensorSpan Reshape(this scoped in TensorSpan tensor, scop // If we contain a 0 stride we can only add dimensions of length 1. else if (tensor.Strides.Contains(0)) { - List origStrides = new List(tensor.Strides.ToArray()); + List origStrides = [.. tensor.Strides]; int lengthOffset = 0; for (int i = 0; i < newLengths.Length; i++) { @@ -1551,12 +1540,12 @@ public static TensorSpan Reshape(this scoped in TensorSpan tensor, scop else ThrowHelper.ThrowArgument_InvalidReshapeDimensions(); } - strides = origStrides.ToArray(); + strides = [.. origStrides]; } else strides = []; - TensorSpan output = new TensorSpan(ref tensor._reference, tensor._shape.LinearLength, newLengths, strides); + TensorSpan output = new TensorSpan(ref tensor._reference, tensor._shape.LinearLength, newLengths, strides, tensor.IsPinned); return output; } @@ -1577,7 +1566,7 @@ public static ReadOnlyTensorSpan Reshape(this scoped in ReadOnlyTensorSpan ThrowHelper.ThrowArgument_CannotReshapeNonContiguousOrDense(); } - nint[] newLengths = lengths.ToArray(); + nint[] newLengths = [.. lengths]; // Calculate wildcard info. int wildcardIndex = lengths.IndexOf(-1); if (wildcardIndex >= 0) @@ -1610,7 +1599,7 @@ public static ReadOnlyTensorSpan Reshape(this scoped in ReadOnlyTensorSpan // If we contain a 0 stride we can only add dimensions of length 1. else if (tensor.Strides.Contains(0)) { - List origStrides = new List(tensor.Strides.ToArray()); + List origStrides = [.. tensor.Strides]; int lengthOffset = 0; for (int i = 0; i < newLengths.Length; i++) { @@ -1626,12 +1615,12 @@ public static ReadOnlyTensorSpan Reshape(this scoped in ReadOnlyTensorSpan else ThrowHelper.ThrowArgument_InvalidReshapeDimensions(); } - strides = origStrides.ToArray(); + strides = [.. origStrides]; } else strides = []; - ReadOnlyTensorSpan output = new ReadOnlyTensorSpan(ref tensor._reference, tensor._shape.LinearLength, newLengths, strides); + ReadOnlyTensorSpan output = new ReadOnlyTensorSpan(ref tensor._reference, tensor._shape.LinearLength, newLengths, strides, tensor.IsPinned); return output; } #endregion @@ -1647,8 +1636,8 @@ public static Tensor Resize(Tensor tensor, ReadOnlySpan lengths) { nint newSize = TensorPrimitives.Product(lengths); T[] values = tensor.IsPinned ? GC.AllocateArray((int)newSize) : (new T[newSize]); - Tensor output = Tensor.Create(values, 0, lengths, []); - ReadOnlySpan span = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref tensor.AsTensorSpan()._reference, tensor._start), (int)tensor._values.Length - tensor._start); + Tensor output = Create(values, lengths, []); + ReadOnlySpan span = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref tensor.AsTensorSpan()._reference, tensor._start), tensor._values.Length - tensor._start); Span ospan = MemoryMarshal.CreateSpan(ref output.AsTensorSpan()._reference, (int)output.FlattenedLength); if (newSize >= span.Length) span.CopyTo(ospan); @@ -1704,7 +1693,7 @@ public static void ResizeTo(scoped in ReadOnlyTensorSpan tensor, in Tensor /// Input . public static Tensor Reverse(in ReadOnlyTensorSpan tensor) { - Tensor output = Tensor.Create(tensor.Lengths); + Tensor output = Create(tensor.Lengths); ReverseDimension(tensor, output, -1); return output; @@ -1718,7 +1707,7 @@ public static Tensor Reverse(in ReadOnlyTensorSpan tensor) /// dimension along which to reverse over. -1 will reverse over all of the dimensions of the left tensor. public static Tensor ReverseDimension(in ReadOnlyTensorSpan tensor, int dimension) { - Tensor output = Tensor.Create(tensor.Lengths); + Tensor output = Create(tensor.Lengths); ReverseDimension(tensor, output, dimension); return output; @@ -1854,9 +1843,9 @@ public static Tensor[] Split(scoped in ReadOnlyTensorSpan tensor, int s nint totalToCopy = tensor.FlattenedLength / splitCount; - nint[] newShape = tensor.Lengths.ToArray(); - nint splitLength = newShape[dimension] / splitCount; - newShape[dimension] = splitLength; + nint[] newLengths = [.. tensor.Lengths]; + nint splitLength = newLengths[dimension] / splitCount; + newLengths[dimension] = splitLength; scoped Span sliceDims = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer lengthsRentedBuffer); for (int i = 0; i < sliceDims.Length; i++) @@ -1868,7 +1857,7 @@ public static Tensor[] Split(scoped in ReadOnlyTensorSpan tensor, int s { sliceDims[(int)dimension] = new NRange(start, start + splitLength); T[] values = new T[(int)totalToCopy]; - outputs[i] = new Tensor(values, 0, newShape, [], tensor._shape.LinearRankOrder); + outputs[i] = new Tensor(values, newLengths, strides: []); tensor.Slice(sliceDims).CopyTo(outputs[i]); start += splitLength; @@ -1897,37 +1886,31 @@ public static Tensor Squeeze(this Tensor tensor) /// The dimension to remove. public static Tensor SqueezeDimension(this Tensor tensor, int dimension) { - if (dimension >= tensor.Rank || dimension < -1) + int rank = tensor.Rank; + + if ((dimension >= rank) || (dimension < -1)) + { ThrowHelper.ThrowArgument_AxisLargerThanRank(); + } - scoped Span lengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer lengthsRentedBuffer); - scoped Span strides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer stridesRentedBuffer); - scoped Span strideOrder = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer stridesOrderRentedBuffer); - int newRank = 0; - int index = 0; + scoped Span lengths = TensorOperation.RentedBuffer.CreateUninitialized(rank, out TensorOperation.RentedBuffer lengthsRentedBuffer); + scoped Span strides = TensorOperation.RentedBuffer.CreateUninitialized(rank, out TensorOperation.RentedBuffer stridesRentedBuffer); if (dimension == -1) { - int removalCount = tensor.Lengths.Count(1); - int removedIndex = 0; - Span removed = TensorOperation.RentedBuffer.CreateUninitialized(removalCount, out TensorOperation.RentedBuffer removedRentedBuffer); - - for (int i = 0; i < tensor.Lengths.Length; i++) + for (int i = 0, index = 0; i < tensor.Lengths.Length; i++) { if (tensor.Lengths[i] != 1) { lengths[index] = tensor.Lengths[i]; strides[index] = tensor.Strides[i]; - newRank++; - strideOrder[index++] = tensor._shape.LinearRankOrder[i]; + index++; } else { - removed[removedIndex++] = tensor._shape.LinearRankOrder[i]; + rank--; } } - SqueezeHelper(removed, strideOrder); - removedRentedBuffer.Dispose(); } else { @@ -1935,29 +1918,20 @@ public static Tensor SqueezeDimension(this Tensor tensor, int dimension { ThrowHelper.ThrowArgument_InvalidSqueezeAxis(); } - int removed = default; - for (int i = 0; i < tensor.Lengths.Length; i++) - { - if (i != dimension) - { - lengths[index] = tensor.Lengths[i]; - strides[index] = tensor.Strides[i]; - newRank++; - strideOrder[index++] = tensor._shape.LinearRankOrder[i]; - } - else - { - removed = tensor._shape.LinearRankOrder[i]; - } - } - SqueezeHelper(removed, strideOrder); + + rank--; + + tensor.Lengths[..dimension].CopyTo(lengths); + tensor.Lengths[(dimension + 1)..].CopyTo(lengths[dimension..]); + + tensor.Strides[..dimension].CopyTo(strides); + tensor.Strides[(dimension + 1)..].CopyTo(strides[dimension..]); } - Tensor output = new Tensor(tensor._values, tensor._start, lengths[..newRank], strides[..newRank], strideOrder[..newRank]); + Tensor output = new Tensor(tensor._values, tensor._start, lengths[..rank], strides[..rank]); lengthsRentedBuffer.Dispose(); stridesRentedBuffer.Dispose(); - stridesOrderRentedBuffer.Dispose(); return output; } @@ -1979,37 +1953,31 @@ public static TensorSpan Squeeze(this scoped in TensorSpan tensor) /// The dimension to remove. public static TensorSpan SqueezeDimension(this scoped in TensorSpan tensor, int dimension) { - if (dimension >= tensor.Rank || dimension < -1) + int rank = tensor.Rank; + + if ((dimension >= rank) || (dimension < -1)) + { ThrowHelper.ThrowArgument_AxisLargerThanRank(); + } - scoped Span lengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer lengthsRentedBuffer); - scoped Span strides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer stridesRentedBuffer); - scoped Span strideOrder = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer stridesOrderRentedBuffer); - int newRank = 0; - int index = 0; + scoped Span lengths = TensorOperation.RentedBuffer.CreateUninitialized(rank, out TensorOperation.RentedBuffer lengthsRentedBuffer); + scoped Span strides = TensorOperation.RentedBuffer.CreateUninitialized(rank, out TensorOperation.RentedBuffer stridesRentedBuffer); if (dimension == -1) { - int removalCount = tensor.Lengths.Count(1); - int removedIndex = 0; - Span removed = TensorOperation.RentedBuffer.CreateUninitialized(removalCount, out TensorOperation.RentedBuffer removedRentedBuffer); - - for (int i = 0; i < tensor.Lengths.Length; i++) + for (int i = 0, index = 0; i < tensor.Lengths.Length; i++) { if (tensor.Lengths[i] != 1) { lengths[index] = tensor.Lengths[i]; strides[index] = tensor.Strides[i]; - newRank++; - strideOrder[index++] = tensor._shape.LinearRankOrder[i]; + index++; } else { - removed[removedIndex++] = tensor._shape.LinearRankOrder[i]; + rank--; } } - SqueezeHelper(removed, strideOrder); - removedRentedBuffer.Dispose(); } else { @@ -2017,29 +1985,20 @@ public static TensorSpan SqueezeDimension(this scoped in TensorSpan ten { ThrowHelper.ThrowArgument_InvalidSqueezeAxis(); } - int removed = default; - for (int i = 0; i < tensor.Lengths.Length; i++) - { - if (i != dimension) - { - lengths[index] = tensor.Lengths[i]; - strides[index] = tensor.Strides[i]; - newRank++; - strideOrder[index++] = tensor._shape.LinearRankOrder[i]; - } - else - { - removed = tensor._shape.LinearRankOrder[i]; - } - } - SqueezeHelper(removed, strideOrder); + + rank--; + + tensor.Lengths[..dimension].CopyTo(lengths); + tensor.Lengths[(dimension + 1)..].CopyTo(lengths[dimension..]); + + tensor.Strides[..dimension].CopyTo(strides); + tensor.Strides[(dimension + 1)..].CopyTo(strides[dimension..]); } - TensorSpan output = new TensorSpan(ref tensor._reference, tensor._shape.LinearLength, lengths[..newRank], strides[..newRank], strideOrder[..newRank]); + TensorSpan output = new TensorSpan(ref tensor._reference, tensor._shape.LinearLength, lengths[..rank], strides[..rank], tensor.IsPinned); lengthsRentedBuffer.Dispose(); stridesRentedBuffer.Dispose(); - stridesOrderRentedBuffer.Dispose(); return output; } @@ -2061,37 +2020,31 @@ public static ReadOnlyTensorSpan Squeeze(this scoped in ReadOnlyTensorSpan /// The dimension to remove. public static ReadOnlyTensorSpan SqueezeDimension(this scoped in ReadOnlyTensorSpan tensor, int dimension) { - if (dimension >= tensor.Rank || dimension < -1) + int rank = tensor.Rank; + + if ((dimension >= rank) || (dimension < -1)) + { ThrowHelper.ThrowArgument_AxisLargerThanRank(); + } - scoped Span lengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer lengthsRentedBuffer); - scoped Span strides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer stridesRentedBuffer); - scoped Span strideOrder = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer stridesOrderRentedBuffer); - int newRank = 0; - int index = 0; + scoped Span lengths = TensorOperation.RentedBuffer.CreateUninitialized(rank, out TensorOperation.RentedBuffer lengthsRentedBuffer); + scoped Span strides = TensorOperation.RentedBuffer.CreateUninitialized(rank, out TensorOperation.RentedBuffer stridesRentedBuffer); if (dimension == -1) { - int removalCount = tensor.Lengths.Count(1); - int removedIndex = 0; - Span removed = TensorOperation.RentedBuffer.CreateUninitialized(removalCount, out TensorOperation.RentedBuffer removedRentedBuffer); - - for (int i = 0; i < tensor.Lengths.Length; i++) + for (int i = 0, index = 0; i < tensor.Lengths.Length; i++) { if (tensor.Lengths[i] != 1) { lengths[index] = tensor.Lengths[i]; strides[index] = tensor.Strides[i]; - newRank++; - strideOrder[index++] = tensor._shape.LinearRankOrder[i]; + index++; } else { - removed[removedIndex++] = tensor._shape.LinearRankOrder[i]; + rank--; } } - SqueezeHelper(removed, strideOrder); - removedRentedBuffer.Dispose(); } else { @@ -2099,57 +2052,23 @@ public static ReadOnlyTensorSpan SqueezeDimension(this scoped in ReadOnlyT { ThrowHelper.ThrowArgument_InvalidSqueezeAxis(); } - int removed = default; - for (int i = 0; i < tensor.Lengths.Length; i++) - { - if (i != dimension) - { - lengths[index] = tensor.Lengths[i]; - strides[index] = tensor.Strides[i]; - newRank++; - strideOrder[index++] = tensor._shape.LinearRankOrder[i]; - } - else - { - removed = tensor._shape.LinearRankOrder[i]; - } - } - SqueezeHelper(removed, strideOrder); + + rank--; + + tensor.Lengths[..dimension].CopyTo(lengths); + tensor.Lengths[(dimension + 1)..].CopyTo(lengths[dimension..]); + + tensor.Strides[..dimension].CopyTo(strides); + tensor.Strides[(dimension + 1)..].CopyTo(strides[dimension..]); } - ReadOnlyTensorSpan output = new ReadOnlyTensorSpan(ref tensor._reference, tensor._shape.LinearLength, lengths[..newRank], strides[..newRank], strideOrder[..newRank]); + ReadOnlyTensorSpan output = new ReadOnlyTensorSpan(ref tensor._reference, tensor._shape.LinearLength, lengths[..rank], strides[..rank], tensor.IsPinned); lengthsRentedBuffer.Dispose(); stridesRentedBuffer.Dispose(); - stridesOrderRentedBuffer.Dispose(); return output; } - - internal static void SqueezeHelper(scoped in Span removed, scoped in Span strideOrder) - { - for (int i = 0; i < strideOrder.Length; i++) - { - for (int j = removed.Length - 1; j >= 0; j--) - { - if (strideOrder[i] > removed[j]) - { - strideOrder[i]--; - } - } - } - } - - internal static void SqueezeHelper(int removed, scoped in Span strideOrder) - { - for (int i = 0; i < strideOrder.Length; i++) - { - if (strideOrder[i] > removed) - { - strideOrder[i]--; - } - } - } #endregion #region Stack @@ -2186,9 +2105,9 @@ public static Tensor StackAlongDimension(int dimension, params ReadOnlySpa Tensor[] outputs = new Tensor[tensors.Length]; for (int i = 0; i < tensors.Length; i++) { - outputs[i] = Tensor.Unsqueeze(tensors[i], dimension); + outputs[i] = Unsqueeze(tensors[i], dimension); } - return Tensor.ConcatenateOnDimension(dimension, outputs); + return ConcatenateOnDimension(dimension, outputs); } /// @@ -2226,9 +2145,9 @@ public static ref readonly TensorSpan StackAlongDimension(scoped ReadOnlyS Tensor[] outputs = new Tensor[tensors.Length]; for (int i = 0; i < tensors.Length; i++) { - outputs[i] = Tensor.Unsqueeze(tensors[i], dimension); + outputs[i] = Unsqueeze(tensors[i], dimension); } - return ref Tensor.ConcatenateOnDimension(dimension, outputs, destination); + return ref ConcatenateOnDimension(dimension, outputs, destination); } #endregion @@ -2279,7 +2198,7 @@ internal static void ToString(in ReadOnlyTensorSpan tensor, ReadOnlySpan tmpTensor = new ReadOnlyTensorSpan(ref Unsafe.Add(ref tensor._reference, i * tensor.Strides[0]), tmpShape); ToString(tmpTensor, maximumLengths[1..], sb, indentLevel + 1); @@ -2339,11 +2258,9 @@ public static Tensor Transpose(Tensor tensor) scoped Span lengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer lengthsRentedBuffer); scoped Span strides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer stridesRentedBuffer); - scoped Span strideOrder = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer stridesOrderRentedBuffer); tensor.Lengths.CopyTo(lengths); tensor.Strides.CopyTo(strides); - tensor._shape.LinearRankOrder.CopyTo(strideOrder); nint temp = lengths[^1]; lengths[^1] = lengths[^2]; @@ -2353,15 +2270,10 @@ public static Tensor Transpose(Tensor tensor) strides[^1] = strides[^2]; strides[^2] = temp; - int tempOrder = strideOrder[^1]; - strideOrder[^1] = strideOrder[^2]; - strideOrder[^2] = tempOrder; - - Tensor output = new Tensor(tensor._values, tensor._start, lengths, strides, strideOrder); + Tensor output = new Tensor(tensor._values, tensor._start, lengths, strides); lengthsRentedBuffer.Dispose(); stridesRentedBuffer.Dispose(); - stridesOrderRentedBuffer.Dispose(); return output; } @@ -2476,7 +2388,7 @@ public static TensorSpan Unsqueeze(this scoped in TensorSpan tensor, in newStrides[dimension] = 0; } - TensorSpan output = new TensorSpan(ref tensor._reference, tensor._shape.LinearLength, newLengths, newStrides); + TensorSpan output = new TensorSpan(ref tensor._reference, tensor._shape.LinearLength, newLengths, newStrides, tensor.IsPinned); lengthsRentedBuffer.Dispose(); stridesRentedBuffer.Dispose(); return output; @@ -2513,7 +2425,7 @@ public static ReadOnlyTensorSpan Unsqueeze(this scoped in ReadOnlyTensorSp newStrides[dimension] = 0; } - ReadOnlyTensorSpan output = new ReadOnlyTensorSpan(ref tensor._reference, tensor._shape.LinearLength, newLengths, newStrides); + ReadOnlyTensorSpan output = new ReadOnlyTensorSpan(ref tensor._reference, tensor._shape.LinearLength, newLengths, newStrides, tensor.IsPinned); lengthsRentedBuffer.Dispose(); stridesRentedBuffer.Dispose(); return output; @@ -2556,7 +2468,7 @@ public static ref readonly TensorSpan Abs(scoped in ReadOnlyTensorSpan public static Tensor Acos(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2583,7 +2495,7 @@ public static ref readonly TensorSpan Acos(scoped in ReadOnlyTensorSpan public static Tensor Acosh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2610,7 +2522,7 @@ public static ref readonly TensorSpan Acosh(scoped in ReadOnlyTensorSpan AcosPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2651,7 +2563,7 @@ public static Tensor Add(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan public static Tensor Add(in ReadOnlyTensorSpan x, T y) where T : IAdditionOperators, IAdditiveIdentity { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -2693,7 +2605,7 @@ public static ref readonly TensorSpan Add(scoped in ReadOnlyTensorSpan public static Tensor Asin(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2720,7 +2632,7 @@ public static ref readonly TensorSpan Asin(scoped in ReadOnlyTensorSpan public static Tensor Asinh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2747,7 +2659,7 @@ public static ref readonly TensorSpan Asinh(scoped in ReadOnlyTensorSpan AsinPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2774,7 +2686,7 @@ public static ref readonly TensorSpan AsinPi(scoped in ReadOnlyTensorSpan< public static Tensor Atan(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2802,7 +2714,7 @@ public static ref readonly TensorSpan Atan(scoped in ReadOnlyTensorSpan public static Tensor Atan2(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) where T : IFloatingPointIeee754 { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -2829,7 +2741,7 @@ public static ref readonly TensorSpan Atan2(scoped in ReadOnlyTensorSpan Atan2(in ReadOnlyTensorSpan x, T y) where T : IFloatingPointIeee754 { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -2856,7 +2768,7 @@ public static ref readonly TensorSpan Atan2(scoped in ReadOnlyTensorSpan Atan2(T x, in ReadOnlyTensorSpan y) where T : IFloatingPointIeee754 { - Tensor destination = Tensor.CreateUninitialized(y.Lengths); + Tensor destination = CreateUninitialized(y.Lengths); TensorOperation.Invoke, T, T>(y, x, destination); return destination; } @@ -2885,7 +2797,7 @@ public static ref readonly TensorSpan Atan2(T x, scoped in ReadOnlyTensorS public static Tensor Atan2Pi(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) where T : IFloatingPointIeee754 { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -2912,7 +2824,7 @@ public static ref readonly TensorSpan Atan2Pi(scoped in ReadOnlyTensorSpan public static Tensor Atan2Pi(in ReadOnlyTensorSpan x, T y) where T : IFloatingPointIeee754 { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -2939,7 +2851,7 @@ public static ref readonly TensorSpan Atan2Pi(scoped in ReadOnlyTensorSpan public static Tensor Atan2Pi(T x, in ReadOnlyTensorSpan y) where T : IFloatingPointIeee754 { - Tensor destination = Tensor.CreateUninitialized(y.Lengths); + Tensor destination = CreateUninitialized(y.Lengths); TensorOperation.Invoke, T, T>(y, x, destination); return destination; } @@ -2967,7 +2879,7 @@ public static ref readonly TensorSpan Atan2Pi(T x, scoped in ReadOnlyTenso public static Tensor Atanh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -2994,7 +2906,7 @@ public static ref readonly TensorSpan Atanh(scoped in ReadOnlyTensorSpan AtanPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3039,7 +2951,7 @@ public static T Average(scoped in ReadOnlyTensorSpan x) public static Tensor BitwiseAnd(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) where T : IBitwiseOperators { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -3066,7 +2978,7 @@ public static ref readonly TensorSpan BitwiseAnd(scoped in ReadOnlyTensorS public static Tensor BitwiseAnd(in ReadOnlyTensorSpan x, T y) where T : IBitwiseOperators { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -3095,7 +3007,7 @@ public static ref readonly TensorSpan BitwiseAnd(scoped in ReadOnlyTensorS public static Tensor BitwiseOr(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) where T : IBitwiseOperators { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -3122,7 +3034,7 @@ public static ref readonly TensorSpan BitwiseOr(scoped in ReadOnlyTensorSp public static Tensor BitwiseOr(in ReadOnlyTensorSpan x, T y) where T : IBitwiseOperators { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -3150,7 +3062,7 @@ public static ref readonly TensorSpan BitwiseOr(scoped in ReadOnlyTensorSp public static Tensor Cbrt(in ReadOnlyTensorSpan x) where T : IRootFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3177,7 +3089,7 @@ public static ref readonly TensorSpan Cbrt(scoped in ReadOnlyTensorSpan public static Tensor Ceiling(in ReadOnlyTensorSpan x) where T : IFloatingPoint { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3206,7 +3118,7 @@ public static Tensor ConvertChecked(in ReadOnlyTensorSpan, IEqualityOperators, INumberBase where TTo : INumberBase { - Tensor destination = Tensor.CreateUninitialized(source.Lengths); + Tensor destination = CreateUninitialized(source.Lengths); TensorOperation.Invoke, TFrom, TTo>(source, destination); return destination; } @@ -3237,7 +3149,7 @@ public static Tensor ConvertSaturating(in ReadOnlyTensorSpan, IEqualityOperators, INumberBase where TTo : INumberBase { - Tensor destination = Tensor.CreateUninitialized(source.Lengths); + Tensor destination = CreateUninitialized(source.Lengths); TensorOperation.Invoke, TFrom, TTo>(source, destination); return destination; } @@ -3268,7 +3180,7 @@ public static Tensor ConvertTruncating(in ReadOnlyTensorSpan, IEqualityOperators, INumberBase where TTo : INumberBase { - Tensor destination = Tensor.CreateUninitialized(source.Lengths); + Tensor destination = CreateUninitialized(source.Lengths); TensorOperation.Invoke, TFrom, TTo>(source, destination); return destination; } @@ -3298,7 +3210,7 @@ public static ref readonly TensorSpan ConvertTruncating(scoped public static Tensor CopySign(in ReadOnlyTensorSpan x, T sign) where T : INumber { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, sign, destination); return destination; } @@ -3311,7 +3223,7 @@ public static Tensor CopySign(in ReadOnlyTensorSpan x, T sign) public static Tensor CopySign(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan sign) where T : INumber { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, sign, destination); return destination; } @@ -3353,7 +3265,7 @@ public static ref readonly TensorSpan CopySign(scoped in ReadOnlyTensorSpa public static Tensor Cos(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3380,7 +3292,7 @@ public static ref readonly TensorSpan Cos(scoped in ReadOnlyTensorSpan public static Tensor Cosh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3408,7 +3320,7 @@ public static ref readonly TensorSpan Cosh(scoped in ReadOnlyTensorSpan public static T CosineSimilarity(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) where T : IRootFunctions { - TensorOperation.ValidateCompatibility(x, y); + TensorOperation.ValidateCompatibility(x, y); ValueTuple result = (T.AdditiveIdentity, T.AdditiveIdentity, T.AdditiveIdentity); TensorOperation.Invoke, T, ValueTuple>(x, y, ref result); return result.Item1 / (T.Sqrt(result.Item2) * T.Sqrt(result.Item3)); @@ -3433,7 +3345,7 @@ public static T CosineSimilarity(in ReadOnlyTensorSpan x, in ReadOnlyTenso public static Tensor CosPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3470,7 +3382,7 @@ public static ref readonly TensorSpan CosPi(scoped in ReadOnlyTensorSpan DegreesToRadians(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3514,7 +3426,7 @@ public static T Distance(scoped in ReadOnlyTensorSpan x, scoped in ReadOnl public static Tensor Divide(in ReadOnlyTensorSpan x, T y) where T : IDivisionOperators { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -3527,7 +3439,7 @@ public static Tensor Divide(in ReadOnlyTensorSpan x, T y) public static Tensor Divide(T x, in ReadOnlyTensorSpan y) where T : IDivisionOperators { - Tensor destination = Tensor.CreateUninitialized(y.Lengths); + Tensor destination = CreateUninitialized(y.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -3614,7 +3526,7 @@ public static T Dot(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) public static Tensor Exp(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3641,7 +3553,7 @@ public static ref readonly TensorSpan Exp(scoped in ReadOnlyTensorSpan public static Tensor Exp10(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3666,7 +3578,7 @@ public static ref readonly TensorSpan Exp10(scoped in ReadOnlyTensorSpan Exp10M1(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3689,7 +3601,7 @@ public static ref readonly TensorSpan Exp10M1(scoped in ReadOnlyTensorSpan public static Tensor Exp2(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3712,7 +3624,7 @@ public static ref readonly TensorSpan Exp2(scoped in ReadOnlyTensorSpan public static Tensor Exp2M1(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3735,7 +3647,7 @@ public static ref readonly TensorSpan Exp2M1(scoped in ReadOnlyTensorSpan< public static Tensor ExpM1(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3758,7 +3670,7 @@ public static ref readonly TensorSpan ExpM1(scoped in ReadOnlyTensorSpan Floor(in ReadOnlyTensorSpan x) where T : IFloatingPoint { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3838,7 +3750,7 @@ public static ref readonly TensorSpan Ieee754Remainder(scoped in ReadOnlyT public static Tensor Ieee754Remainder(in ReadOnlyTensorSpan x, T y) where T : IFloatingPointIeee754 { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -3861,7 +3773,7 @@ public static ref readonly TensorSpan Ieee754Remainder(scoped in ReadOnlyT public static Tensor Ieee754Remainder(T x, in ReadOnlyTensorSpan y) where T : IFloatingPointIeee754 { - Tensor destination = Tensor.CreateUninitialized(y.Lengths); + Tensor destination = CreateUninitialized(y.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -3885,7 +3797,7 @@ public static ref readonly TensorSpan Ieee754Remainder(T x, scoped in Read public static Tensor ILogB(in ReadOnlyTensorSpan x) where T : IFloatingPointIeee754 { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, int>(x, destination); return destination; } @@ -3957,7 +3869,7 @@ public static nint IndexOfMinMagnitude(scoped in ReadOnlyTensorSpan x) public static Tensor LeadingZeroCount(in ReadOnlyTensorSpan x) where T : IBinaryInteger { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -3984,7 +3896,7 @@ public static ref readonly TensorSpan LeadingZeroCount(scoped in ReadOnlyT public static Tensor Log(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4031,7 +3943,7 @@ public static ref readonly TensorSpan Log(scoped in ReadOnlyTensorSpan public static Tensor Log(in ReadOnlyTensorSpan x, T y) where T : ILogarithmicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4057,7 +3969,7 @@ public static ref readonly TensorSpan Log(scoped in ReadOnlyTensorSpan public static Tensor Log10(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4084,7 +3996,7 @@ public static ref readonly TensorSpan Log10(scoped in ReadOnlyTensorSpan Log10P1(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4111,7 +4023,7 @@ public static ref readonly TensorSpan Log10P1(scoped in ReadOnlyTensorSpan public static Tensor Log2(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4138,7 +4050,7 @@ public static ref readonly TensorSpan Log2(scoped in ReadOnlyTensorSpan public static Tensor Log2P1(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4165,7 +4077,7 @@ public static ref readonly TensorSpan Log2P1(scoped in ReadOnlyTensorSpan< public static Tensor LogP1(in ReadOnlyTensorSpan x) where T : ILogarithmicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4229,7 +4141,7 @@ public static ref readonly TensorSpan Max(scoped in ReadOnlyTensorSpan public static Tensor Max(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4292,7 +4204,7 @@ public static ref readonly TensorSpan MaxMagnitude(scoped in ReadOnlyTenso public static Tensor MaxMagnitude(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4355,7 +4267,7 @@ public static ref readonly TensorSpan MaxMagnitudeNumber(scoped in ReadOnl public static Tensor MaxMagnitudeNumber(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4418,7 +4330,7 @@ public static ref readonly TensorSpan MaxNumber(scoped in ReadOnlyTensorSp public static Tensor MaxNumber(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4481,7 +4393,7 @@ public static ref readonly TensorSpan Min(scoped in ReadOnlyTensorSpan public static Tensor Min(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4544,7 +4456,7 @@ public static ref readonly TensorSpan MinMagnitude(scoped in ReadOnlyTenso public static Tensor MinMagnitude(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4607,7 +4519,7 @@ public static ref readonly TensorSpan MinMagnitudeNumber(scoped in ReadOnl public static Tensor MinMagnitudeNumber(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4670,7 +4582,7 @@ public static ref readonly TensorSpan MinNumber(scoped in ReadOnlyTensorSp public static Tensor MinNumber(in ReadOnlyTensorSpan x, T y) where T : INumber { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4697,7 +4609,7 @@ public static ref readonly TensorSpan MinNumber(scoped in ReadOnlyTensorSp public static Tensor Multiply(in ReadOnlyTensorSpan x, T y) where T : IMultiplyOperators, IMultiplicativeIdentity { - Tensor destination = Tensor.Create(x.Lengths); + Tensor destination = Create(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4752,7 +4664,7 @@ public static ref readonly TensorSpan Multiply(scoped in ReadOnlyTensorSpa public static Tensor Negate(in ReadOnlyTensorSpan x) where T : IUnaryNegationOperators { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4789,7 +4701,7 @@ public static T Norm(scoped in ReadOnlyTensorSpan x) public static Tensor OnesComplement(in ReadOnlyTensorSpan x) where T : IBitwiseOperators { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4812,7 +4724,7 @@ public static ref readonly TensorSpan OnesComplement(scoped in ReadOnlyTen public static Tensor PopCount(in ReadOnlyTensorSpan x) where T : IBinaryInteger { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4859,7 +4771,7 @@ public static ref readonly TensorSpan Pow(scoped in ReadOnlyTensorSpan public static Tensor Pow(in ReadOnlyTensorSpan x, T y) where T : IPowerFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4882,7 +4794,7 @@ public static ref readonly TensorSpan Pow(scoped in ReadOnlyTensorSpan public static Tensor Pow(T x, in ReadOnlyTensorSpan y) where T : IPowerFunctions { - Tensor destination = Tensor.CreateUninitialized(y.Lengths); + Tensor destination = CreateUninitialized(y.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } @@ -4918,7 +4830,7 @@ public static T Product(scoped in ReadOnlyTensorSpan x) public static Tensor RadiansToDegrees(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4941,7 +4853,7 @@ public static ref readonly TensorSpan RadiansToDegrees(scoped in ReadOnlyT public static Tensor Reciprocal(in ReadOnlyTensorSpan x) where T : IFloatingPoint { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -4965,7 +4877,7 @@ public static ref readonly TensorSpan Reciprocal(scoped in ReadOnlyTensorS public static Tensor RootN(in ReadOnlyTensorSpan x, int n) where T : IRootFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, n, destination); return destination; } @@ -4991,7 +4903,7 @@ public static ref readonly TensorSpan RootN(scoped in ReadOnlyTensorSpan RotateLeft(in ReadOnlyTensorSpan x, int rotateAmount) where T : IBinaryInteger { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, rotateAmount, destination); return destination; } @@ -5018,7 +4930,7 @@ public static ref readonly TensorSpan RotateLeft(scoped in ReadOnlyTensorS public static Tensor RotateRight(in ReadOnlyTensorSpan x, int rotateAmount) where T : IBinaryInteger { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, rotateAmount, destination); return destination; } @@ -5043,7 +4955,7 @@ public static ref readonly TensorSpan RotateRight(scoped in ReadOnlyTensor public static Tensor Round(in ReadOnlyTensorSpan x) where T : IFloatingPoint { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5066,7 +4978,7 @@ public static ref readonly TensorSpan Round(scoped in ReadOnlyTensorSpan Round(in ReadOnlyTensorSpan x, int digits, MidpointRounding mode) where T : IFloatingPoint { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, Tuple, T>(x, Tuple.Create(digits, mode), destination); return destination; } @@ -5090,7 +5002,7 @@ public static ref readonly TensorSpan Round(scoped in ReadOnlyTensorSpan Round(in ReadOnlyTensorSpan x, int digits) where T : IFloatingPoint { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, Tuple, T>(x, Tuple.Create(digits, MidpointRounding.ToEven), destination); return destination; } @@ -5113,7 +5025,7 @@ public static ref readonly TensorSpan Round(scoped in ReadOnlyTensorSpan Round(in ReadOnlyTensorSpan x, MidpointRounding mode) where T : IFloatingPoint { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, Tuple, T>(x, Tuple.Create(0, mode), destination); return destination; } @@ -5137,7 +5049,7 @@ public static ref readonly TensorSpan Round(scoped in ReadOnlyTensorSpan Sigmoid(in ReadOnlyTensorSpan x) where T : IExponentialFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5162,7 +5074,7 @@ public static ref readonly TensorSpan Sigmoid(scoped in ReadOnlyTensorSpan public static Tensor Sin(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5187,7 +5099,7 @@ public static ref readonly TensorSpan Sin(scoped in ReadOnlyTensorSpan public static Tensor Sinh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5210,7 +5122,7 @@ public static ref readonly TensorSpan Sinh(scoped in ReadOnlyTensorSpan public static Tensor SinPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5236,7 +5148,7 @@ public static Tensor SoftMax(in ReadOnlyTensorSpan x) T sumExp = T.AdditiveIdentity; TensorOperation.Invoke, T, T>(x, ref sumExp); - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, sumExp, destination); return destination; } @@ -5264,7 +5176,7 @@ public static ref readonly TensorSpan SoftMax(scoped in ReadOnlyTensorSpan public static Tensor Sqrt(in ReadOnlyTensorSpan x) where T : IRootFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5420,7 +5332,7 @@ internal static T SumOfSquares(scoped in ReadOnlyTensorSpan x) public static Tensor Tan(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5443,7 +5355,7 @@ public static ref readonly TensorSpan Tan(scoped in ReadOnlyTensorSpan public static Tensor Tanh(in ReadOnlyTensorSpan x) where T : IHyperbolicFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5466,7 +5378,7 @@ public static ref readonly TensorSpan Tanh(scoped in ReadOnlyTensorSpan public static Tensor TanPi(in ReadOnlyTensorSpan x) where T : ITrigonometricFunctions { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5489,7 +5401,7 @@ public static ref readonly TensorSpan TanPi(scoped in ReadOnlyTensorSpan TrailingZeroCount(in ReadOnlyTensorSpan x) where T : IBinaryInteger { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5512,7 +5424,7 @@ public static ref readonly TensorSpan TrailingZeroCount(scoped in ReadOnly public static Tensor Truncate(in ReadOnlyTensorSpan x) where T : IFloatingPoint { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, destination); return destination; } @@ -5561,7 +5473,7 @@ public static ref readonly TensorSpan Xor(scoped in ReadOnlyTensorSpan public static Tensor Xor(in ReadOnlyTensorSpan x, T y) where T : IBitwiseOperators { - Tensor destination = Tensor.CreateUninitialized(x.Lengths); + Tensor destination = CreateUninitialized(x.Lengths); TensorOperation.Invoke, T, T>(x, y, destination); return destination; } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorDimensionSpan_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorDimensionSpan_1.cs index 78622c79c59f09..0823dbb638f49a 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorDimensionSpan_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorDimensionSpan_1.cs @@ -27,9 +27,12 @@ internal TensorDimensionSpan(TensorSpan tensor, int dimension) _tensor = tensor; _length = TensorPrimitives.Product(tensor.Lengths[..dimension]); _dimension = dimension; - _sliceShape = TensorShape.Create((dimension != tensor.Rank) ? tensor.Lengths[dimension..] : [1], tensor.Strides[dimension..]); + _sliceShape = TensorShape.Create((dimension != tensor.Rank) ? tensor.Lengths[dimension..] : [1], tensor.Strides[dimension..], tensor.IsPinned); } + /// Gets true if the slices that exist within the tracked dimension are dense; otherwise, false. + public bool IsDense => _sliceShape.IsDense; + /// Gets the length of the tensor dimension span. public nint Length => _length; @@ -50,6 +53,12 @@ public TensorSpan this[nint index] } } + /// Defines an implicit conversion of a tensor dimension span to a readonly tensor dimension span. + /// The tensor dimension span to convert to a readonly tensor dimension span. + /// The tensor dimension span that corresponds to . + public static implicit operator ReadOnlyTensorDimensionSpan(scoped in TensorDimensionSpan tensorDimension) => + new ReadOnlyTensorDimensionSpan(tensorDimension._tensor, tensorDimension._dimension); + /// Gets an enumerator for the readonly tensor dimension span. public Enumerator GetEnumerator() => new Enumerator(this); diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorOperation.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorOperation.cs index d3b702d050cb7f..fa983d5fff8581 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorOperation.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorOperation.cs @@ -11,7 +11,7 @@ namespace System.Numerics.Tensors internal static class TensorOperation { public static void Invoke(in TensorSpan x) - where TOperation : TensorOperation.IOperation + where TOperation : IOperation { scoped Span indexes = RentedBuffer.Create(x.Rank, x.Strides, out nint linearOffset, out RentedBuffer rentedBuffer); @@ -27,7 +27,7 @@ ref Unsafe.Add(ref x._reference, linearOffset) } public static bool Invoke(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y) - where TOperation : TensorOperation.IBinaryOperation_Tensor_Tensor + where TOperation : IBinaryOperation_Tensor_Tensor { bool result = false; @@ -59,7 +59,7 @@ ref result } public static bool Invoke(in ReadOnlyTensorSpan x, TArg y) - where TOperation : TensorOperation.IBinaryOperation_Tensor_Scalar + where TOperation : IBinaryOperation_Tensor_Scalar { bool result = false; @@ -87,7 +87,7 @@ ref result } public static void Invoke(in TensorSpan destination, TArg scalar) - where TOperation : TensorOperation.IUnaryOperation_Scalar + where TOperation : IUnaryOperation_Scalar { scoped Span indexes = RentedBuffer.Create(destination.Rank, destination.Strides, out nint linearOffset, out RentedBuffer rentedBuffer); @@ -104,7 +104,7 @@ ref Unsafe.Add(ref destination._reference, linearOffset), } public static void Invoke(in ReadOnlyTensorSpan x, in TensorSpan destination) - where TOperation : TensorOperation.IUnaryOperation_Tensor + where TOperation : IUnaryOperation_Tensor { scoped Span xIndexes = RentedBuffer.Create(destination.Rank, x.Strides, out nint xLinearOffset, out RentedBuffer xRentedBuffer); scoped Span destinationIndexes = RentedBuffer.Create(destination.Rank, destination.Strides, out nint destinationLinearOffset, out RentedBuffer destinationRentedBuffer); @@ -125,7 +125,7 @@ ref Unsafe.Add(ref destination._reference, destinationLinearOffset) } public static void ReverseInvoke(in ReadOnlyTensorSpan x, in TensorSpan destination) - where TOperation : TensorOperation.IUnaryOperation_Tensor + where TOperation : IUnaryOperation_Tensor { scoped Span xIndexes = RentedBuffer.Create(destination.Rank, x.Strides, out nint xLinearOffset, out RentedBuffer xRentedBuffer); scoped Span destinationIndexes = RentedBuffer.Create(destination.Rank, destination.Strides, out nint _, out RentedBuffer destinationRentedBuffer); @@ -154,7 +154,7 @@ ref Unsafe.Add(ref destination._reference, destinationLinearOffset) // For copyto/flattento public static void Invoke(in ReadOnlyTensorSpan x, in Span destination) - where TOperation : TensorOperation.IUnaryOperation_Tensor + where TOperation : IUnaryOperation_Tensor { scoped Span xIndexes = RentedBuffer.Create(x.Rank, x.Strides, out nint xLinearOffset, out RentedBuffer xRentedBuffer); nint destinationIndex = -1; @@ -174,7 +174,7 @@ ref Unsafe.Add(ref destination[0], destinationIndex) } public static void Invoke(in ReadOnlyTensorSpan x, ref TResult destination) - where TOperation : TensorOperation.IUnaryReduction_Tensor + where TOperation : IUnaryReduction_Tensor { scoped Span xIndexes = RentedBuffer.Create(x.Rank, x.Strides, out nint xLinearOffset, out RentedBuffer xRentedBuffer); @@ -192,7 +192,7 @@ ref destination } public static void Invoke(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y, in TensorSpan destination) - where TOperation : TensorOperation.IBinaryOperation_Tensor_Tensor + where TOperation : IBinaryOperation_Tensor_Tensor { scoped Span xIndexes = RentedBuffer.Create(destination.Rank, x.Strides, out nint xLinearOffset, out RentedBuffer xRentedBuffer); scoped Span yIndexes = RentedBuffer.Create(destination.Rank, y.Strides, out nint yLinearOffset, out RentedBuffer yRentedBuffer); @@ -217,11 +217,11 @@ ref Unsafe.Add(ref destination._reference, destinationLinearOffset) } public static void Invoke(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y, in TensorSpan destination) - where TOperation : TensorOperation.IBinaryOperation_Tensor_Tensor + where TOperation : IBinaryOperation_Tensor_Tensor => Invoke(in x, in y, in destination); public static void Invoke(in ReadOnlyTensorSpan x, in ReadOnlyTensorSpan y, ref TResult result) - where TOperation : TensorOperation.IBinaryOperation_Tensor_Tensor + where TOperation : IBinaryOperation_Tensor_Tensor { ref readonly TensorShape destinationShape = ref ((x._shape.FlattenedLength > y._shape.FlattenedLength) ? ref x._shape : ref y._shape); @@ -246,14 +246,14 @@ ref result [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Invoke(in ReadOnlyTensorSpan x, TArg y, in TensorSpan destination) - where TOperation : TensorOperation.IBinaryOperation_Tensor_Scalar => Invoke(in x, y, in destination); + where TOperation : IBinaryOperation_Tensor_Scalar => Invoke(in x, y, in destination); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Invoke(in ReadOnlyTensorSpan x, int y, in TensorSpan destination) - where TOperation : TensorOperation.IBinaryOperation_Tensor_Int32 => Invoke(in x, y, in destination); + where TOperation : IBinaryOperation_Tensor_Int32 => Invoke(in x, y, in destination); public static void Invoke(in ReadOnlyTensorSpan x, TArg2 y, in TensorSpan destination) - where TOperation : TensorOperation.IBinaryOperation_Tensor_Scalar + where TOperation : IBinaryOperation_Tensor_Scalar { scoped Span xIndexes = RentedBuffer.Create(destination.Rank, x.Strides, out nint xLinearOffset, out RentedBuffer xRentedBuffer); scoped Span destinationIndexes = RentedBuffer.Create(destination.Rank, destination.Strides, out nint destinationLinearOffset, out RentedBuffer destinationRentedBuffer); @@ -275,7 +275,7 @@ ref Unsafe.Add(ref destination._reference, destinationLinearOffset) } public static void Invoke(TArg x, in ReadOnlyTensorSpan y, in TensorSpan destination) - where TOperation : TensorOperation.IBinaryOperation_Scalar_Tensor + where TOperation : IBinaryOperation_Scalar_Tensor { scoped Span xIndexes = RentedBuffer.Create(destination.Rank, y.Strides, out nint xLinearOffset, out RentedBuffer xRentedBuffer); scoped Span destinationIndexes = RentedBuffer.Create(destination.Rank, destination.Strides, out nint destinationLinearOffset, out RentedBuffer destinationRentedBuffer); @@ -297,7 +297,7 @@ ref Unsafe.Add(ref destination._reference, destinationLinearOffset) } public static void Invoke(in ReadOnlyTensorSpan x, TArg2 y, ref TResult result) - where TOperation : TensorOperation.IBinaryOperation_Tensor_Scalar + where TOperation : IBinaryOperation_Tensor_Scalar { scoped Span xIndexes = RentedBuffer.Create(x.Rank, x.Strides, out nint xLinearOffset, out RentedBuffer xRentedBuffer); @@ -316,7 +316,7 @@ ref result } public static void Invoke(in ReadOnlyTensorSpan x, TArg y, ref TResult result) - where TOperation : TensorOperation.IBinaryOperation_Tensor_Scalar => Invoke(in x, y, ref result); + where TOperation : IBinaryOperation_Tensor_Scalar => Invoke(in x, y, ref result); public static void ValidateCompatibility(in ReadOnlyTensorSpan x, in ReadOnlySpan lengths) { diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs index d77e749dcecb59..e1c560dc91d30e 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorShape.cs @@ -2,6 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -15,8 +18,8 @@ namespace System.Numerics.Tensors // // We avoid allocating for small ranks up to MaxInlineRank in size and allocate a // single buffer for larger ranks. This buffer will always be precisely `InlineBufferCount * rank` - // in size where the first rank elements are the length, the next rank elements are - // the strides, and then the next rank elements are the rank order. + // in size where the first rank elements are the length and the next rank elements are + // the strides. // // We cache both a flattened length and a linear length to avoid recalculating these // key properties. The flattened length is the total number of elements represented @@ -40,35 +43,34 @@ internal enum TensorFlags : uint IsDense = (1 << 0), IsBroadcast = (1 << 1), HasAnyDenseDimensions = (1 << 2), + IsPinned = (1 << 3), } - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] internal readonly struct TensorShape : IEquatable { // The layout of the fields here is very particular and is intentionally designed to - // be compact and cache-friendly. The current size on a 64-bit system is 108+4 bytes + // be compact and cache-friendly. The current size on a 64-bit system is 112 bytes // and this fits within 2 cache lines, where 64 bytes is the typical cache line size. // // The TensorSpan and ReadOnlyTensorSpan types then track a byref field which takes // an additional 8 bytes. This leaves 8 bytes still available for use for other scenarios // if required. - internal const int MaxInlineRank = 4; - private const int InlineBufferCount = 3; + internal const int MaxInlineRank = 5; + private const int InlineBufferCount = 2; private readonly nint[]? _metadata; // 8 bytes private readonly nint _flattenedLength; // 8 bytes private readonly nint _linearLength; // 8 bytes - private readonly InlineBuffer _inlineLengths; // 4x8 bytes (32) - private readonly InlineBuffer _inlineStrides; // 4x8 bytes (32) - private readonly InlineBuffer _inlineLinearRankOrder; // 4x4 bytes (16) + private readonly InlineBuffer _inlineLengths; // 5x8 bytes (40) + private readonly InlineBuffer _inlineStrides; // 5x8 bytes (40) - private readonly int _rank; - private readonly TensorFlags _flags; // 4 bytes + private readonly int _rank; // 4 bytes + private readonly TensorFlags _flags; // 4 bytes - private TensorShape(nint linearLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, scoped ReadOnlySpan linearRankOrder) + private TensorShape(nint linearLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, TensorFlags flags) { int rank = lengths.Length; @@ -81,7 +83,6 @@ private TensorShape(nint linearLength, scoped ReadOnlySpan lengths, scoped scoped Span destinationLengths; scoped Span destinationStrides; - scoped Span destinationLinearRankOrder; if (rank > MaxInlineRank) { @@ -89,10 +90,6 @@ private TensorShape(nint linearLength, scoped ReadOnlySpan lengths, scoped destinationLengths = metadata.AsSpan(rank * 0, rank); destinationStrides = metadata.AsSpan(rank * 1, rank); - destinationLinearRankOrder = MemoryMarshal.CreateSpan( - ref Unsafe.As(ref metadata[rank * 2]), - rank - ); _metadata = metadata; } @@ -100,70 +97,23 @@ ref Unsafe.As(ref metadata[rank * 2]), { destinationLengths = ((Span)_inlineLengths)[..rank]; destinationStrides = ((Span)_inlineStrides)[..rank]; - destinationLinearRankOrder = ((Span)_inlineLinearRankOrder)[..rank]; - } - - if (linearRankOrder.Length == 0) - { - // The linearRankOrder is expected to be in "row-major" order, that is otherwise - // known as "big-endian" order where the dimensions that are farthest apart - // (i.e. have the greatest impact to computing a linear index) appear first. - // - // So, when no rank order is specified by the user we simply populate this - // as 0 to rank-1. In the case strides is also not specified, this will be - // correct "as is"; otherwise, we will sort this based on which stride is - // largest prior to validating the user provided strides. - - for (int i = 0; i < destinationLinearRankOrder.Length; i++) - { - destinationLinearRankOrder[i] = i; - } } - else if (linearRankOrder.Length != rank) - { - ThrowHelper.ThrowArgument_InvalidTensorShape(); - } - else - { - // If a rank order was specified, then we need to ensure that it is valid, - // which should mean that when sorting we have values from 0 to rank-1. - // - // While this does copy the rank order twice, the typical rank is expected - // to be small and so the cost should be minimal. - - linearRankOrder.CopyTo(destinationLinearRankOrder); - destinationLinearRankOrder.Sort(); - - for (int i = 0; i < linearRankOrder.Length; i++) - { - if (destinationLinearRankOrder[i] != i) - { - ThrowHelper.ThrowArgument_InvalidTensorShape(); - } - } - linearRankOrder.CopyTo(destinationLinearRankOrder); - } + // Copy the lengths over up front + lengths.CopyTo(destinationLengths); nint flattenedLength = 1; nint maximumLinearIndex = 0; if (strides.Length == 0) { - // When no strides are specified, we need to computing them based on the given - // rank order. We use destinationLinearRankOrder here to ensure that we have a - // correct order even if no rank order was specified by the user. - // - // To do this, we simply iterate the rank order from least to most significant - // so that the strides match the expected order, being the product of all previous - // dimension lengths. + // When no strides are specified, we need to computing them simply + // by calculating the product of the lengths at each iteration. - for (int i = 0; i < destinationLinearRankOrder.Length; i++) + for (int n = 0; n < rank; n++) { - int rankIndex = destinationLinearRankOrder.Length - (i + 1); - int linearRankIndex = destinationLinearRankOrder[rankIndex]; - - nint length = lengths[linearRankIndex]; + int i = rank - (n + 1); + nint length = lengths[i]; if (length < 0) { @@ -179,17 +129,15 @@ ref Unsafe.As(ref metadata[rank * 2]), else { stride = 0; - _flags |= TensorFlags.IsBroadcast; + flags |= TensorFlags.IsBroadcast; } - destinationLengths[linearRankIndex] = length; - destinationStrides[linearRankIndex] = stride; - + destinationStrides[i] = stride; flattenedLength = checked(flattenedLength * length); } // When the strides are automatically computed, then we must be dense - _flags |= (TensorFlags.IsDense | TensorFlags.HasAnyDenseDimensions); + flags |= (TensorFlags.IsDense | TensorFlags.HasAnyDenseDimensions); } else if (strides.Length != lengths.Length) { @@ -198,7 +146,7 @@ ref Unsafe.As(ref metadata[rank * 2]), else { // If a strides was specified, then we need to ensure it is valid as well, - // which should mean that when sorted by rank order (most to least significant) + // which should mean that when sorted from most to least significant // each stride should be greater than or equal to the previous stride multiplied // by the dimension length. // @@ -210,53 +158,69 @@ ref Unsafe.As(ref metadata[rank * 2]), // n+1. This makes it convenient to support implicit broadcasting where higher dimensions // aren't actually stored in memory. + int maxStrideIndex = rank - 1; nint minimumNonZeroStride = 1; - var sortedWithIndex = destinationLinearRankOrder.ToArray() - .Select((value, index) => new { Value = value, Index = index }) - .OrderBy(x => x.Value) - .ToArray(); - int[] sortedOrder = sortedWithIndex.Select(x => x.Index).ToArray(); - bool isDense = true; + int[]? stridesOrderArray; + InlineBuffer stridesOrderBuffer; + scoped Span stridesOrder; - for (int i = 0; i < destinationLinearRankOrder.Length; i++) + if (rank > MaxInlineRank) { - int rankIndex = destinationLinearRankOrder.Length - (i + 1); - int linearRankIndex = sortedOrder[rankIndex]; + stridesOrderArray = ArrayPool.Shared.Rent(rank); + stridesOrder = stridesOrderArray.AsSpan(0, rank); + } + else + { + Unsafe.SkipInit(out stridesOrderBuffer); + stridesOrder = ((Span)stridesOrderBuffer)[..rank]; + } - if (linearRankIndex != rankIndex) - { - // We cannot be dense if we aren't following linear order - isDense = false; - } + for (int i = 0; i < rank; i++) + { + stridesOrder[i] = i; + } + + strides.CopyTo(destinationStrides); + MemoryExtensions.Sort(destinationStrides, stridesOrder); + + bool isDense = true; - nint length = lengths[linearRankIndex]; + for (int i = 0; i < rank; i++) + { + int strideIndex = stridesOrder[i]; + nint length = lengths[strideIndex]; if (length < 0) { ThrowHelper.ThrowArgument_LengthIsNegative(); } - nint stride = strides[linearRankIndex]; + nint sortedStride = destinationStrides[i]; - if (stride < 0) + if (sortedStride < 0) { ThrowHelper.ThrowArgument_StrideIsNegative(); } - if (stride != 0) + if (sortedStride != 0) { - if (stride < minimumNonZeroStride) + if (sortedStride < minimumNonZeroStride) { // The next stride needs to be at least as big as the // previous stride times the dimension length, otherwise - // the linear rank ordering is incorrect + // we aren't in a linear order. ThrowHelper.ThrowArgument_InvalidTensorShape(); } - else if (stride != minimumNonZeroStride) + else if (sortedStride != minimumNonZeroStride) + { + isDense = false; + } + else if (strideIndex > maxStrideIndex) { isDense = false; } + maxStrideIndex = strideIndex; if (length <= 1) { @@ -266,12 +230,12 @@ ref Unsafe.As(ref metadata[rank * 2]), ThrowHelper.ThrowArgument_InvalidTensorShape(); } - minimumNonZeroStride = checked(length * stride); - maximumLinearIndex = checked(maximumLinearIndex + (minimumNonZeroStride - stride)); + minimumNonZeroStride = checked(length * sortedStride); + maximumLinearIndex = checked(maximumLinearIndex + (minimumNonZeroStride - sortedStride)); } else { - _flags |= TensorFlags.IsBroadcast; + flags |= TensorFlags.IsBroadcast; if (length != 1) { @@ -280,19 +244,17 @@ ref Unsafe.As(ref metadata[rank * 2]), } } - destinationLengths[linearRankIndex] = length; - destinationStrides[linearRankIndex] = stride; - flattenedLength = checked(flattenedLength * length); } + strides.CopyTo(destinationStrides); if (isDense) { - _flags |= (TensorFlags.IsDense | TensorFlags.HasAnyDenseDimensions); + flags |= (TensorFlags.IsDense | TensorFlags.HasAnyDenseDimensions); } else if (CalculateHasAnyDenseDimensions(lengths, strides)) { - _flags |= TensorFlags.HasAnyDenseDimensions; + flags |= TensorFlags.HasAnyDenseDimensions; } } @@ -314,19 +276,18 @@ ref Unsafe.As(ref metadata[rank * 2]), _linearLength = minimumLinearLength; _rank = rank; + _flags = flags; ValidateState(); } - private TensorShape(nint flattenedLength, nint linearLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, scoped ReadOnlySpan linearRankOrder, int rank, TensorFlags flags) + private TensorShape(nint flattenedLength, nint linearLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, TensorFlags flags) { - Debug.Assert(lengths.Length == rank); + int rank = lengths.Length; Debug.Assert(strides.Length == rank); - Debug.Assert(linearRankOrder.Length == rank); scoped Span destinationLengths; scoped Span destinationStrides; - scoped Span destinationLinearRankOrder; if (rank > MaxInlineRank) { @@ -334,10 +295,6 @@ private TensorShape(nint flattenedLength, nint linearLength, scoped ReadOnlySpan destinationLengths = metadata.AsSpan(rank * 0, rank); destinationStrides = metadata.AsSpan(rank * 1, rank); - destinationLinearRankOrder = MemoryMarshal.CreateSpan( - ref Unsafe.As(ref metadata[rank * 2]), - rank - ); _metadata = metadata; } @@ -345,7 +302,6 @@ ref Unsafe.As(ref metadata[rank * 2]), { destinationLengths = ((Span)_inlineLengths)[..rank]; destinationStrides = ((Span)_inlineStrides)[..rank]; - destinationLinearRankOrder = ((Span)_inlineLinearRankOrder)[..rank]; } _flattenedLength = flattenedLength; @@ -353,7 +309,6 @@ ref Unsafe.As(ref metadata[rank * 2]), lengths.CopyTo(destinationLengths); strides.CopyTo(destinationStrides); - linearRankOrder.CopyTo(destinationLinearRankOrder); _rank = rank; _flags = flags; @@ -361,16 +316,18 @@ ref Unsafe.As(ref metadata[rank * 2]), ValidateState(); } + public nint FlattenedLength => _flattenedLength; + public bool HasAnyDenseDimensions => (_flags & TensorFlags.HasAnyDenseDimensions) != 0; public bool IsBroadcast => (_flags & TensorFlags.IsBroadcast) != 0; public bool IsDense => (_flags & TensorFlags.IsDense) != 0; - public nint FlattenedLength => _flattenedLength; - public bool IsEmpty => _flattenedLength == 0; + public bool IsPinned => (_flags & TensorFlags.IsPinned) != 0; + public nint LinearLength => _linearLength; [UnscopedRef] @@ -390,26 +347,6 @@ public ReadOnlySpan Lengths } } - [UnscopedRef] - public ReadOnlySpan LinearRankOrder - { - get - { - if (_metadata is not nint[] metadata) - { - return ((ReadOnlySpan)_inlineLinearRankOrder)[.._rank]; - } - else - { - int rank = metadata.Length / InlineBufferCount; - return MemoryMarshal.CreateSpan( - ref Unsafe.As(ref metadata[rank * 2]), - rank - ); - } - } - } - public int Rank => _rank; [UnscopedRef] @@ -449,29 +386,19 @@ public ReadOnlySpan Strides } ReadOnlySpan leftLengths = left.Lengths; - ReadOnlySpan leftLinearRankOrder = left.LinearRankOrder; ReadOnlySpan leftStrides = left.Strides; ReadOnlySpan rightLengths = right.Lengths; - ReadOnlySpan rightLinearRankOrder = right.LinearRankOrder; ReadOnlySpan rightStrides = right.Strides; for (int i = 0; i < rank; i++) { - // We need to compare lengths and strides based on the linearRankOrder - // to ensure that two tensors representing the same memory, but where - // the shapes are logically, but not physically, transposed are considered - // equal. - - int leftRankIndex = leftLinearRankOrder[i]; - int rightRankIndex = rightLinearRankOrder[i]; - - if (leftLengths[leftRankIndex] != rightLengths[rightRankIndex]) + if (leftLengths[i] != rightLengths[i]) { return false; } - if (leftStrides[leftRankIndex] != rightStrides[rightRankIndex]) + if (leftStrides[i] != rightStrides[i]) { return false; } @@ -622,8 +549,12 @@ public static bool AdjustToNextIndex(Span ranges, int dimension, ReadOnl if (ranges[i].Start.Value >= lengths[i]) { ranges[i] = 0..1; + if (i == 0) + { return false; + } + ranges[i - 1] = new NRange(ranges[i - 1].Start.Value + 1, ranges[i - 1].End.Value + 1); } } @@ -799,7 +730,7 @@ public static TensorShape Create(Array? array) linearLength, lengths, strides: [], - linearRankOrder: [] + TensorFlags.None ); if (lengthsArray is not null) @@ -894,7 +825,7 @@ public static TensorShape Create(Array? array, scoped ReadOnlySpan start, s ThrowHelper.ThrowArgument_StartIndexOutOfBounds(); } - TensorShape result = new TensorShape(linearLength - computedOffset, lengths, strides, linearRankOrder: []); + TensorShape result = new TensorShape(linearLength - computedOffset, lengths, strides, TensorFlags.None); if (intermediateLengthsArray is not null) { @@ -916,52 +847,33 @@ public static TensorShape Create(Array? array, scoped ReadOnlySpan start, s return default; } - public static TensorShape Create(scoped ReadOnlySpan lengths) - => new TensorShape(linearLength: -1, lengths, strides: [], linearRankOrder: []); - - public static TensorShape Create(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) - => new TensorShape(linearLength: -1, lengths, strides, linearRankOrder: []); + public static TensorShape Create(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) + { + TensorFlags flags = pinned ? TensorFlags.IsPinned : TensorFlags.None; + return new TensorShape(linearLength: -1, lengths: lengths, strides: strides, flags: flags); + } public static TensorShape Create(T[]? array) { if (array is not null) { int linearLength = array.Length; - return new TensorShape( flattenedLength: linearLength, - linearLength, + linearLength: linearLength, lengths: [linearLength], strides: [1], - linearRankOrder: [0], - rank: 1, TensorFlags.IsDense | TensorFlags.HasAnyDenseDimensions ); } return default; } - public static TensorShape Create(T[]? array, scoped ReadOnlySpan lengths) - { - if (array is not null) - { - int linearLength = array.Length; - return new TensorShape(linearLength, lengths, strides: [], linearRankOrder: []); - } - - if (lengths.Length != 0) - { - ThrowHelper.ThrowArgument_InvalidTensorShape(); - } - return default; - } - public static TensorShape Create(T[]? array, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) { if (array is not null) { - int linearLength = array.Length; - return new TensorShape(linearLength, lengths, strides, linearRankOrder: []); + return new TensorShape(array.Length, lengths, strides, TensorFlags.None); } if ((lengths.Length != 0) || (strides.Length != 0)) @@ -983,7 +895,7 @@ public static TensorShape Create(T[]? array, int start, scoped ReadOnlySpan(T[]? array, int start, scoped ReadOnlySpan(T[]? array, int start, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, scoped ReadOnlySpan linearRankOrder) - { - if (array is not null) - { - int linearLength = array.Length; - - if ((start < 0) || (start > linearLength)) - { - ThrowHelper.ThrowArgument_StartIndexOutOfBounds(); - } - - linearLength -= start; - return new TensorShape(linearLength, lengths, strides, linearRankOrder); - } - else if (start != 0) - { - ThrowHelper.ThrowArgument_StartIndexOutOfBounds(); - } - - if ((lengths.Length != 0) || (strides.Length != 0)) - { - ThrowHelper.ThrowArgument_InvalidTensorShape(); - } - return default; - } - - public static TensorShape Create(ref T reference, nint linearLength) + public static TensorShape Create(ref T reference, nint linearLength, bool pinned) { if (!Unsafe.IsNullRef(ref reference)) { + TensorFlags flags = pinned ? TensorFlags.IsPinned : TensorFlags.None; + flags |= TensorFlags.IsDense | TensorFlags.HasAnyDenseDimensions; + return new TensorShape( flattenedLength: linearLength, - linearLength, + linearLength: linearLength, lengths: [linearLength], strides: [1], - linearRankOrder: [0], - rank: 1, - TensorFlags.IsDense | TensorFlags.HasAnyDenseDimensions + flags ); } else if (linearLength != 0) @@ -1044,17 +931,12 @@ public static TensorShape Create(ref T reference, nint linearLength) return default; } - public static TensorShape Create(ref T reference, nint linearLength, scoped ReadOnlySpan lengths) - => Create(ref reference, linearLength, lengths, strides: [], linearRankOrder: []); - - public static TensorShape Create(ref T reference, nint linearLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) - => Create(ref reference, linearLength, lengths, strides, linearRankOrder: []); - - public static TensorShape Create(ref T reference, nint linearLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, scoped ReadOnlySpan linearRankOrder) + public static TensorShape Create(ref T reference, nint linearLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) { if (!Unsafe.IsNullRef(ref reference)) { - return new TensorShape(linearLength, lengths, strides, linearRankOrder); + TensorFlags flags = pinned ? TensorFlags.IsPinned : TensorFlags.None; + return new TensorShape(linearLength, lengths, strides, flags); } else if (linearLength != 0) { @@ -1069,13 +951,10 @@ public static TensorShape Create(ref T reference, nint linearLength, scoped R } public static unsafe TensorShape Create(T* address, nint linearLength) - => Create(ref Unsafe.AsRef(address), linearLength); - - public static unsafe TensorShape Create(T* address, nint linearLength, scoped ReadOnlySpan lengths) - => Create(ref Unsafe.AsRef(address), linearLength, lengths, strides: []); + => Create(ref Unsafe.AsRef(address), linearLength, pinned: true); - public static unsafe TensorShape Create(T* address, nint linearLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) - => Create(ref Unsafe.AsRef(address), linearLength, lengths, strides); + public static unsafe TensorShape Create(T* address, nint linearLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides = default) + => Create(ref Unsafe.AsRef(address), linearLength, lengths, strides, pinned: true); public override bool Equals([NotNullWhen(true)] object? obj) => (obj is TensorShape other) && (this == other); @@ -1184,23 +1063,21 @@ public TensorShape Slice(ReadOnlySpan state, out nint ReadOnlySpan previousLengths = Lengths; ReadOnlySpan previousStrides = Strides; - ReadOnlySpan linearRankOrder = LinearRankOrder; if ((state.Length != previousLengths.Length) || - (state.Length != linearRankOrder.Length) || (state.Length != previousStrides.Length)) { ThrowHelper.ThrowArgumentOutOfRangeException(); } - // The previous strides and rank order persist in the new shape with - // only the lengths having changed based on the new starting index. + // The previous strides persist in the new shape with only + // the lengths having changed based on the new starting index. // // Accordingly, we can also simplify some of the checks as we can // assume that the previousShape is already valid and the new shape // will strictly be the same size or smaller. - TensorFlags flags = TensorFlags.None; + TensorFlags flags = IsPinned ? TensorFlags.IsPinned : TensorFlags.None; nint flattenedLength = 1; nint maximumLinearIndex = 0; @@ -1209,21 +1086,14 @@ public TensorShape Slice(ReadOnlySpan state, out nint nint computedOffset = 0; bool isDense = true; - for (int i = 0; i < linearRankOrder.Length; i++) + for (int n = 0; n < rank; n++) { - int rankIndex = linearRankOrder.Length - (i + 1); - int linearRankIndex = linearRankOrder[rankIndex]; - - if (rankIndex != linearRankIndex) - { - // We cannot be dense if we aren't following linear order - isDense = false; - } + int i = rank - (n + 1); - nint previousLength = previousLengths[linearRankIndex]; - nint previousStride = previousStrides[linearRankIndex]; + nint previousLength = previousLengths[i]; + nint previousStride = previousStrides[i]; - (nint offset, nint length) = TGetOffsetAndLength.GetOffsetAndLength(state[linearRankIndex], previousLength); + (nint offset, nint length) = TGetOffsetAndLength.GetOffsetAndLength(state[i], previousLength); nint stride = (length > 1) ? previousStride : 0; if (stride != 0) @@ -1246,8 +1116,8 @@ public TensorShape Slice(ReadOnlySpan state, out nint } } - intermediateLengths[linearRankIndex] = length; - intermediateStrides[linearRankIndex] = stride; + intermediateLengths[i] = length; + intermediateStrides[i] = stride; minimumNonZeroStride = stride * length; @@ -1275,8 +1145,6 @@ public TensorShape Slice(ReadOnlySpan state, out nint minimumLinearLength, intermediateLengths, intermediateStrides, - linearRankOrder, - rank, flags ); diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs index 4b694d7d72f57d..3a420c18ff2059 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpanDebugView.cs @@ -6,8 +6,6 @@ namespace System.Numerics.Tensors { - - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] internal sealed class TensorSpanDebugView { private readonly T[] _array; diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan_1.cs index d1d3ee856502ba..de7904a341bc35 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan_1.cs @@ -21,8 +21,10 @@ namespace System.Numerics.Tensors /// The type of the elements within the tensor span. [DebuggerTypeProxy(typeof(TensorSpanDebugView<>))] [DebuggerDisplay("{ToString(),raw}")] - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public readonly ref struct TensorSpan +#if NET9_0_OR_GREATER + : ITensor, T> +#endif { /// public static TensorSpan Empty => default; @@ -34,7 +36,7 @@ public readonly ref struct TensorSpan /// is covariant and its type is not exactly T[]. public TensorSpan(T[]? array) { - ThrowHelper.ThrowIfArrayTypeMismatch(array); + ThrowHelper.ThrowIfArrayTypeMismatch(array); _shape = TensorShape.Create(array); _reference = ref (array is not null) @@ -45,20 +47,13 @@ public TensorSpan(T[]? array) /// /// is covariant and its type is not exactly T[]. public TensorSpan(T[]? array, scoped ReadOnlySpan lengths) - { - ThrowHelper.ThrowIfArrayTypeMismatch(array); - - _shape = TensorShape.Create(array, lengths); - _reference = ref (array is not null) - ? ref MemoryMarshal.GetArrayDataReference(array) - : ref Unsafe.NullRef(); - } + : this(array, lengths, strides: []) { } /// /// is covariant and its type is not exactly T[]. public TensorSpan(T[]? array, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) { - ThrowHelper.ThrowIfArrayTypeMismatch(array); + ThrowHelper.ThrowIfArrayTypeMismatch(array); _shape = TensorShape.Create(array, lengths, strides); _reference = ref (array is not null) @@ -70,7 +65,7 @@ public TensorSpan(T[]? array, scoped ReadOnlySpan lengths, scoped ReadOnly /// is covariant and its type is not exactly T[]. public TensorSpan(T[]? array, int start, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) { - ThrowHelper.ThrowIfArrayTypeMismatch(array); + ThrowHelper.ThrowIfArrayTypeMismatch(array); _shape = TensorShape.Create(array, start, lengths, strides); _reference = ref (array is not null) @@ -82,23 +77,19 @@ public TensorSpan(T[]? array, int start, scoped ReadOnlySpan lengths, scop public TensorSpan(Span span) { ref T reference = ref MemoryMarshal.GetReference(span); - _shape = TensorShape.Create(ref reference, span.Length); + _shape = TensorShape.Create(ref reference, span.Length, pinned: false); _reference = ref reference; } /// public TensorSpan(Span span, scoped ReadOnlySpan lengths) - { - ref T reference = ref MemoryMarshal.GetReference(span); - _shape = TensorShape.Create(ref reference, span.Length, lengths); - _reference = ref reference; - } + : this(span, lengths, strides: []) { } /// public TensorSpan(Span span, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) { ref T reference = ref MemoryMarshal.GetReference(span); - _shape = TensorShape.Create(ref reference, span.Length, lengths, strides); + _shape = TensorShape.Create(ref reference, span.Length, lengths, strides, pinned: false); _reference = ref reference; } @@ -137,10 +128,7 @@ public unsafe TensorSpan(T* data, nint dataLength) /// [CLSCompliant(false)] public unsafe TensorSpan(T* data, nint dataLength, scoped ReadOnlySpan lengths) - { - _shape = TensorShape.Create(data, dataLength, lengths); - _reference = ref Unsafe.AsRef(data); - } + : this(data, dataLength, lengths, strides: []) { } /// [CLSCompliant(false)] @@ -150,27 +138,9 @@ public unsafe TensorSpan(T* data, nint dataLength, scoped ReadOnlySpan len _reference = ref Unsafe.AsRef(data); } - internal TensorSpan(ref T data, nint dataLength) + internal TensorSpan(ref T data, nint dataLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) { - _shape = TensorShape.Create(ref data, dataLength); - _reference = ref data; - } - - internal TensorSpan(ref T data, nint dataLength, scoped ReadOnlySpan lengths) - { - _shape = TensorShape.Create(ref data, dataLength, lengths); - _reference = ref data; - } - - internal TensorSpan(ref T data, nint dataLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) - { - _shape = TensorShape.Create(ref data, dataLength, lengths, strides); - _reference = ref data; - } - - internal TensorSpan(ref T data, nint dataLength, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, scoped ReadOnlySpan linearRankOrder) - { - _shape = TensorShape.Create(ref data, dataLength, lengths, strides, linearRankOrder); + _shape = TensorShape.Create(ref data, dataLength, lengths, strides, pinned); _reference = ref data; } @@ -211,6 +181,9 @@ public TensorSpan this[params scoped ReadOnlySpan ranges] /// public bool IsEmpty => _shape.IsEmpty; + /// + public bool IsPinned => _shape.IsPinned; + /// [UnscopedRef] public ReadOnlySpan Lengths => _shape.Lengths; @@ -344,11 +317,94 @@ ref Unsafe.Add(ref _reference, linearOffset), /// public bool TryFlattenTo(scoped Span destination) => AsReadOnlyTensorSpan().TryFlattenTo(destination); +#if NET9_0_OR_GREATER + // + // IReadOnlyTensor + // + + object? IReadOnlyTensor.this[params scoped ReadOnlySpan indexes] => this[indexes]; + + object? IReadOnlyTensor.this[params scoped ReadOnlySpan indexes] => this[indexes]; + + // + // IReadOnlyTensor + // + + ref readonly T IReadOnlyTensor, T>.this[params scoped ReadOnlySpan indexes] => ref this[indexes]; + + ref readonly T IReadOnlyTensor, T>.this[params scoped ReadOnlySpan indexes] => ref this[indexes]; + + ReadOnlyTensorDimensionSpan IReadOnlyTensor, T>.GetDimensionSpan(int dimension) => GetDimensionSpan(dimension); + + ref readonly T IReadOnlyTensor, T>.GetPinnableReference() => ref GetPinnableReference(); + + TensorSpan IReadOnlyTensor, T>.ToDenseTensor() + { + TensorSpan result = this; + + if (!IsDense) + { + result = Tensor.Create(Lengths, IsPinned); + CopyTo(result); + } + + return result; + } + + // + // ITensor + // + + bool ITensor.IsReadOnly => false; + + object? ITensor.this[params scoped ReadOnlySpan indexes] + { + get => this[indexes]; + + set + { + this[indexes] = (T)value!; + } + } + + object? ITensor.this[params scoped ReadOnlySpan indexes] + { + get => this[indexes]; + + set + { + this[indexes] = (T)value!; + } + } + + void ITensor.Fill(object value) => Fill(value is T t ? t : throw new ArgumentException($"Cannot convert {value} to {typeof(T)}")); + + // + // ITensor + // + + static TensorSpan ITensor, T>.Create(scoped ReadOnlySpan lengths, bool pinned) => Tensor.Create(lengths, pinned); + + static TensorSpan ITensor, T>.Create(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.Create(lengths, strides, pinned); + + static TensorSpan ITensor, T>.CreateUninitialized(scoped ReadOnlySpan lengths, bool pinned) => Tensor.CreateUninitialized(lengths, pinned); + + static TensorSpan ITensor, T>.CreateUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.CreateUninitialized(lengths, strides, pinned); + + TensorSpan ITensor, T>.AsTensorSpan() => this; + + TensorSpan ITensor, T>.AsTensorSpan(params scoped ReadOnlySpan startIndexes) => Slice(startIndexes); + + TensorSpan ITensor, T>.AsTensorSpan(params scoped ReadOnlySpan startIndexes) => Slice(startIndexes); + + TensorSpan ITensor, T>.AsTensorSpan(params scoped ReadOnlySpan ranges) => Slice(ranges); +#endif + /// Enumerates the elements of a tensor span. public ref struct Enumerator : IEnumerator { private readonly TensorSpan _span; - private nint[] _indexes; + private readonly nint[] _indexes; private nint _linearOffset; private nint _itemsEnumerated; @@ -394,7 +450,7 @@ public void Reset() // IDisposable // - void IDisposable.Dispose() { } + readonly void IDisposable.Dispose() { } // // IEnumerator diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor_1.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor_1.cs index b209109eba8374..5bcddc999fdcc8 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor_1.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor_1.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -16,110 +15,66 @@ namespace System.Numerics.Tensors /// /// Represents a tensor. /// - [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] - public sealed class Tensor : ITensor, T> + public sealed class Tensor : ITensor, T>, IEnumerable { /// Gets an empty tensor. public static Tensor Empty { get; } = new(); internal readonly TensorShape _shape; internal readonly T[] _values; - internal readonly int _start; - internal readonly bool _isPinned; - - internal Tensor(scoped ReadOnlySpan lengths, bool pinned) - { - _shape = TensorShape.Create(lengths); - _values = GC.AllocateArray(checked((int)(_shape.LinearLength)), pinned); - - _start = 0; - _isPinned = pinned; - } internal Tensor(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) { - _shape = TensorShape.Create(lengths, strides); + _shape = TensorShape.Create(lengths, strides, pinned); _values = GC.AllocateArray(checked((int)(_shape.LinearLength)), pinned); - _start = 0; - _isPinned = pinned; } internal Tensor(T[]? array) { _shape = TensorShape.Create(array); _values = (array is not null) ? array : []; - - _start = 0; - _isPinned = false; - } - - internal Tensor(T[]? array, scoped ReadOnlySpan lengths) - { - _shape = TensorShape.Create(array, lengths); - _values = (array is not null) ? array : []; - _start = 0; - _isPinned = false; } internal Tensor(T[]? array, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) { _shape = TensorShape.Create(array, lengths, strides); _values = (array is not null) ? array : []; - _start = 0; - _isPinned = false; } internal Tensor(T[]? array, int start, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides) { _shape = TensorShape.Create(array, start, lengths, strides); _values = (array is not null) ? array : []; - _start = start; - _isPinned = false; } - internal Tensor(T[]? array, int start, scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, scoped ReadOnlySpan linearRankOrder) + internal Tensor(T[] array, in TensorShape shape) { - _shape = TensorShape.Create(array, start, lengths, strides, linearRankOrder); - _values = (array is not null) ? array : []; - - _start = start; - _isPinned = false; - } - - internal Tensor(T[] array, in TensorShape shape, bool isPinned) - { - ThrowHelper.ThrowIfArrayTypeMismatch(array); + ThrowHelper.ThrowIfArrayTypeMismatch(array); _shape = shape; _values = array; - _start = 0; - _isPinned = isPinned; } - internal Tensor(T[] array, int start, in TensorShape shape, bool isPinned) + internal Tensor(T[] array, int start, in TensorShape shape) { - ThrowHelper.ThrowIfArrayTypeMismatch(array); + ThrowHelper.ThrowIfArrayTypeMismatch(array); _shape = shape; _values = array; - _start = start; - _isPinned = isPinned; } private Tensor() { _shape = default; _values = []; - _start = 0; - _isPinned = false; } /// @@ -154,7 +109,7 @@ public Tensor this[params ReadOnlySpan ranges] public bool IsEmpty => _shape.IsEmpty; /// - public bool IsPinned => _isPinned; + public bool IsPinned => _shape.IsPinned; /// public ReadOnlySpan Lengths => _shape.Lengths; @@ -242,7 +197,8 @@ public ref T GetPinnableReference() return ref ret; } - /// + /// Pins and gets a to the backing memory. + /// public unsafe MemoryHandle GetPinnedHandle() { GCHandle handle = GCHandle.Alloc(_values, GCHandleType.Pinned); @@ -260,8 +216,7 @@ public Tensor Slice(params ReadOnlySpan startIndexes) return new Tensor( _values, (int)(_start + linearOffset), - in shape, - _isPinned + in shape ); } @@ -276,8 +231,7 @@ public Tensor Slice(params ReadOnlySpan startIndexes) return new Tensor( _values, (int)(_start + linearOffset), - in shape, - _isPinned + in shape ); } @@ -292,8 +246,7 @@ public Tensor Slice(params ReadOnlySpan ranges) return new Tensor( _values, (int)(_start + linearOffset), - in shape, - _isPinned + in shape ); } @@ -401,9 +354,9 @@ public string ToString(params ReadOnlySpan maximumLengths) static Tensor ITensor, T>.Create(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.Create(lengths, strides, pinned); - static Tensor ITensor, T>.CreateUninitialized(scoped ReadOnlySpan lengths, bool pinned) => Tensor.Create(lengths, pinned); + static Tensor ITensor, T>.CreateUninitialized(scoped ReadOnlySpan lengths, bool pinned) => Tensor.CreateUninitialized(lengths, pinned); - static Tensor ITensor, T>.CreateUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.Create(lengths, strides, pinned); + static Tensor ITensor, T>.CreateUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned) => Tensor.CreateUninitialized(lengths, strides, pinned); /// Enumerates the elements of a tensor. public struct Enumerator : IEnumerator diff --git a/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj b/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj index bfd91bb49d1f93..a8f53d7696c8fb 100644 --- a/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj +++ b/src/libraries/System.Numerics.Tensors/tests/Net8Tests/System.Numerics.Tensors.Net8.Tests.csproj @@ -11,8 +11,6 @@ $(NetCoreAppCurrent) true $(DefineConstants);SNT_NET8_TESTS - - $(NoWarn);SYSLIB5001 diff --git a/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj b/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj index 366c2a83688a2e..c885e5acb0c496 100644 --- a/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj +++ b/src/libraries/System.Numerics.Tensors/tests/System.Numerics.Tensors.Tests.csproj @@ -3,8 +3,6 @@ $(NetCoreAppCurrent);$(NetFrameworkCurrent) true - - $(NoWarn);SYSLIB5001 diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs index 3f1ff1ff0e25f5..41c995428b765e 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs @@ -104,7 +104,7 @@ public void TensorExtensionsSpanInSpanOut(PerformCalculationSpanInSpanOut FillTensor(data); Tensor x = Tensor.Create(data, tensorLength, []); - + Tensor results = tensorOperation(x); Assert.Equal(tensorLength, results.Lengths); @@ -616,7 +616,7 @@ public static void TensorFactoryCreateTests() var t1 = Tensor.Create((Span)[2, 2], [1, 1], false); }); } - + [Fact] public static void TensorCosineSimilarityTests() { @@ -1116,19 +1116,19 @@ public static void TensorStackTests() // stacking 2x2 tensors along dimension 1 Tensor v1 = Tensor.Create([1, 2, 3, 4], lengths: [2, 2]); Tensor v2 = Tensor.Create([10, 20, 30, 40], lengths: [2, 2]); - + resultTensor = Tensor.StackAlongDimension(1, [v1, v2]); - + Assert.Equal(3, resultTensor.Rank); Assert.Equal(2, resultTensor.Lengths[0]); Assert.Equal(2, resultTensor.Lengths[1]); Assert.Equal(2, resultTensor.Lengths[2]); - + Assert.Equal(1, resultTensor[0, 0, 0]); Assert.Equal(2, resultTensor[0, 0, 1]); Assert.Equal(10, resultTensor[0, 1, 0]); Assert.Equal(20, resultTensor[0, 1, 1]); - + Assert.Equal(3, resultTensor[1, 0, 0]); Assert.Equal(4, resultTensor[1, 0, 1]); Assert.Equal(30, resultTensor[1, 1, 0]); @@ -2723,7 +2723,7 @@ public void TensorFilteredUpdateTest() [Fact] public void TensorObjectFillTests() { - ITensor tensor = (ITensor)new Tensor(new int[4], new nint[] { 2, 2 }); + ITensor tensor = Tensor.Create(new int[4], new nint[] { 2, 2 }); tensor.Fill(5); Assert.Equal(5, tensor[0, 0]); @@ -2744,7 +2744,7 @@ public void TensorObjectFillTests() [Fact] public void TensorObjectIndexerTests() { - ITensor tensor = new Tensor(new int[] { 1, 2, 3, 4 }, new nint[] { 2, 2 }); + ITensor tensor = Tensor.Create(new int[] { 1, 2, 3, 4 }, new nint[] { 2, 2 }); Assert.Equal(1, tensor[new nint[] { 0, 0 }]); Assert.Equal(2, tensor[new nint[] { 0, 1 }]); @@ -2775,7 +2775,7 @@ public void TensorObjectIndexerTests() [Fact] public void TensorGetPinnedHandleTests() { - Tensor tensor = new Tensor(new int[] { 1, 2, 3, 4 }, new nint[] { 2, 2 }); + Tensor tensor = Tensor.Create(new int[] { 1, 2, 3, 4 }, new nint[] { 2, 2 }); using MemoryHandle handle = tensor.GetPinnedHandle(); unsafe diff --git a/src/tools/illink/src/linker/CompatibilitySuppressions.xml b/src/tools/illink/src/linker/CompatibilitySuppressions.xml index a7c4bcb0e5fa06..58644dc9d4a19e 100644 --- a/src/tools/illink/src/linker/CompatibilitySuppressions.xml +++ b/src/tools/illink/src/linker/CompatibilitySuppressions.xml @@ -1,10 +1,6 @@ - + - - CP0001 - T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypesEx - CP0001 T:ILLink.Shared.DataFlow.Box`1 @@ -97,6 +93,10 @@ CP0001 T:ILLink.Shared.MessageSubCategory + + CP0001 + T:ILLink.Shared.TrimAnalysis.DiagnosticContext + CP0001 T:ILLink.Shared.TrimAnalysis.FieldReferenceValue @@ -533,6 +533,10 @@ CP0001 T:Mono.Linker.XmlDependencyRecorder + + CP0001 + T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypesEx + CP0001 T:System.Reflection.AssemblyNameHelpers @@ -557,10 +561,6 @@ CP0001 T:System.Reflection.RuntimeAssemblyName - - CP0001 - T:ILLink.Shared.TrimAnalysis.DiagnosticContext - CP0002 F:Mono.Linker.AnnotationStore.assembly_actions @@ -985,6 +985,10 @@ CP0002 M:Mono.Linker.LinkContext.get_IgnoreUnresolved + + CP0002 + M:Mono.Linker.LinkContext.get_KeepComInterfaces + CP0002 M:Mono.Linker.LinkContext.get_KeepMembersForDebugger @@ -1041,6 +1045,10 @@ CP0002 M:Mono.Linker.LinkContext.get_Pipeline + + CP0002 + M:Mono.Linker.LinkContext.get_PreserveSymbolPaths + CP0002 M:Mono.Linker.LinkContext.get_Resolver @@ -1065,6 +1073,10 @@ CP0002 M:Mono.Linker.LinkContext.get_SymbolReaderProvider + + CP0002 + M:Mono.Linker.LinkContext.get_SystemModuleName + CP0002 M:Mono.Linker.LinkContext.get_Tracer @@ -1285,6 +1297,10 @@ CP0002 M:Mono.Linker.LinkContext.set_IgnoreUnresolved(System.Boolean) + + CP0002 + M:Mono.Linker.LinkContext.set_KeepComInterfaces(System.Boolean) + CP0002 M:Mono.Linker.LinkContext.set_KeepMembersForDebugger(System.Boolean) @@ -1321,6 +1337,10 @@ CP0002 M:Mono.Linker.LinkContext.set_OutputDirectory(System.String) + + CP0002 + M:Mono.Linker.LinkContext.set_PreserveSymbolPaths(System.Boolean) + CP0002 M:Mono.Linker.LinkContext.set_SingleWarn(System.Collections.Generic.Dictionary{System.String,System.Boolean}) @@ -1337,6 +1357,10 @@ CP0002 M:Mono.Linker.LinkContext.set_SymbolReaderProvider(Mono.Cecil.Cil.ISymbolReaderProvider) + + CP0002 + M:Mono.Linker.LinkContext.set_SystemModuleName(System.String) + CP0002 M:Mono.Linker.LinkContext.set_TrimAction(Mono.Linker.AssemblyAction) @@ -1497,30 +1521,6 @@ CP0002 M:Mono.Linker.Steps.SubStepsDispatcher.Process(Mono.Linker.LinkContext) - - CP0002 - M:Mono.Linker.LinkContext.get_KeepComInterfaces - - - CP0002 - M:Mono.Linker.LinkContext.get_PreserveSymbolPaths - - - CP0002 - M:Mono.Linker.LinkContext.get_SystemModuleName - - - CP0002 - M:Mono.Linker.LinkContext.set_KeepComInterfaces(System.Boolean) - - - CP0002 - M:Mono.Linker.LinkContext.set_PreserveSymbolPaths(System.Boolean) - - - CP0002 - M:Mono.Linker.LinkContext.set_SystemModuleName(System.String) - CP0008 T:Mono.Linker.LinkContext