diff --git a/src/libraries/System.Numerics.Tensors/Directory.Build.props b/src/libraries/System.Numerics.Tensors/Directory.Build.props
deleted file mode 100644
index 36078bccbf7aa8..00000000000000
--- a/src/libraries/System.Numerics.Tensors/Directory.Build.props
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- true
- false
-
-
\ No newline at end of file
diff --git a/src/libraries/System.Numerics.Tensors/README.md b/src/libraries/System.Numerics.Tensors/README.md
index 026563de81306d..6190da60e77c51 100644
--- a/src/libraries/System.Numerics.Tensors/README.md
+++ b/src/libraries/System.Numerics.Tensors/README.md
@@ -1,2 +1,3 @@
# System.Numerics.Tensors
-This library has not been shipped publicly and is not accepting contributions at this time.
\ No newline at end of file
+
+Provides APIs for performing primitive operations over tensors represented by spans of memory.
diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs
index 3161a4c7e780ce..c657a43a054dd6 100644
--- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs
+++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.cs
@@ -6,151 +6,27 @@
namespace System.Numerics.Tensors
{
- public static partial class ArrayTensorExtensions
+ public static class TensorPrimitives
{
- public static System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor(this System.Array array, bool reverseStride = false) { throw null; }
- public static System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor(this T[,,] array, bool reverseStride = false) { throw null; }
- public static System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor(this T[,] array, bool reverseStride = false) { throw null; }
- public static System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor(this T[] array) { throw null; }
- public static System.Numerics.Tensors.SparseTensor ToSparseTensor(this System.Array array, bool reverseStride = false) { throw null; }
- public static System.Numerics.Tensors.SparseTensor ToSparseTensor(this T[,,] array, bool reverseStride = false) { throw null; }
- public static System.Numerics.Tensors.SparseTensor ToSparseTensor(this T[,] array, bool reverseStride = false) { throw null; }
- public static System.Numerics.Tensors.SparseTensor ToSparseTensor(this T[] array) { throw null; }
- public static System.Numerics.Tensors.DenseTensor ToTensor(this System.Array array, bool reverseStride = false) { throw null; }
- public static System.Numerics.Tensors.DenseTensor ToTensor(this T[,,] array, bool reverseStride = false) { throw null; }
- public static System.Numerics.Tensors.DenseTensor ToTensor(this T[,] array, bool reverseStride = false) { throw null; }
- public static System.Numerics.Tensors.DenseTensor ToTensor(this T[] array) { throw null; }
- }
- public partial class CompressedSparseTensor : System.Numerics.Tensors.Tensor
- {
- public CompressedSparseTensor(System.Memory values, System.Memory compressedCounts, System.Memory indices, int nonZeroCount, System.ReadOnlySpan dimensions, bool reverseStride = false) : base (default(System.Array), default(bool)) { }
- public CompressedSparseTensor(System.ReadOnlySpan dimensions, bool reverseStride = false) : base (default(System.Array), default(bool)) { }
- public CompressedSparseTensor(System.ReadOnlySpan dimensions, int capacity, bool reverseStride = false) : base (default(System.Array), default(bool)) { }
- public int Capacity { get { throw null; } }
- public System.Memory CompressedCounts { get { throw null; } }
- public System.Memory Indices { get { throw null; } }
- public override T this[System.ReadOnlySpan indices] { get { throw null; } set { } }
- public int NonZeroCount { get { throw null; } }
- public System.Memory Values { get { throw null; } }
- public override System.Numerics.Tensors.Tensor Clone() { throw null; }
- public override System.Numerics.Tensors.Tensor CloneEmpty(System.ReadOnlySpan dimensions) { throw null; }
- public override T GetValue(int index) { throw null; }
- public override System.Numerics.Tensors.Tensor Reshape(System.ReadOnlySpan dimensions) { throw null; }
- public override void SetValue(int index, T value) { }
- public override System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor() { throw null; }
- public override System.Numerics.Tensors.DenseTensor ToDenseTensor() { throw null; }
- public override System.Numerics.Tensors.SparseTensor ToSparseTensor() { throw null; }
- }
- public partial class DenseTensor : System.Numerics.Tensors.Tensor
- {
- public DenseTensor(int length) : base (default(System.Array), default(bool)) { }
- public DenseTensor(System.Memory memory, System.ReadOnlySpan dimensions, bool reverseStride = false) : base (default(System.Array), default(bool)) { }
- public DenseTensor(System.ReadOnlySpan dimensions, bool reverseStride = false) : base (default(System.Array), default(bool)) { }
- public System.Memory Buffer { get { throw null; } }
- public override System.Numerics.Tensors.Tensor Clone() { throw null; }
- public override System.Numerics.Tensors.Tensor CloneEmpty(System.ReadOnlySpan dimensions) { throw null; }
- protected override void CopyTo(T[] array, int arrayIndex) { }
- public override T GetValue(int index) { throw null; }
- protected override int IndexOf(T item) { throw null; }
- public override System.Numerics.Tensors.Tensor Reshape(System.ReadOnlySpan dimensions) { throw null; }
- public override void SetValue(int index, T value) { }
- }
- public partial class SparseTensor : System.Numerics.Tensors.Tensor
- {
- public SparseTensor(System.ReadOnlySpan dimensions, bool reverseStride = false, int capacity = 0) : base (default(System.Array), default(bool)) { }
- public int NonZeroCount { get { throw null; } }
- public override System.Numerics.Tensors.Tensor Clone() { throw null; }
- public override System.Numerics.Tensors.Tensor CloneEmpty(System.ReadOnlySpan dimensions) { throw null; }
- public override T GetValue(int index) { throw null; }
- public override System.Numerics.Tensors.Tensor Reshape(System.ReadOnlySpan dimensions) { throw null; }
- public override void SetValue(int index, T value) { }
- public override System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor() { throw null; }
- public override System.Numerics.Tensors.DenseTensor ToDenseTensor() { throw null; }
- public override System.Numerics.Tensors.SparseTensor ToSparseTensor() { throw null; }
- }
- public static partial class Tensor
- {
- public static System.Numerics.Tensors.Tensor CreateFromDiagonal(System.Numerics.Tensors.Tensor diagonal) { throw null; }
- public static System.Numerics.Tensors.Tensor CreateFromDiagonal(System.Numerics.Tensors.Tensor diagonal, int offset) { throw null; }
- public static System.Numerics.Tensors.Tensor CreateIdentity(int size) { throw null; }
- public static System.Numerics.Tensors.Tensor CreateIdentity(int size, bool columMajor) { throw null; }
- public static System.Numerics.Tensors.Tensor CreateIdentity(int size, bool columMajor, T oneValue) { throw null; }
- }
- public abstract partial class Tensor : System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable
- {
- protected Tensor(System.Array fromArray, bool reverseStride) { }
- protected Tensor(int length) { }
- protected Tensor(System.ReadOnlySpan dimensions, bool reverseStride) { }
- public System.ReadOnlySpan Dimensions { get { throw null; } }
- public bool IsFixedSize { get { throw null; } }
- public bool IsReadOnly { get { throw null; } }
- public bool IsReversedStride { get { throw null; } }
- public virtual T this[params int[] indices] { get { throw null; } set { } }
- public virtual T this[System.ReadOnlySpan indices] { get { throw null; } set { } }
- public long Length { get { throw null; } }
- public int Rank { get { throw null; } }
- public System.ReadOnlySpan Strides { get { throw null; } }
- int System.Collections.Generic.ICollection.Count { get { throw null; } }
- T System.Collections.Generic.IList.this[int index] { get { throw null; } set { } }
- int System.Collections.Generic.IReadOnlyCollection.Count { get { throw null; } }
- T System.Collections.Generic.IReadOnlyList.this[int index] { get { throw null; } }
- int System.Collections.ICollection.Count { get { throw null; } }
- bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
- object System.Collections.ICollection.SyncRoot { get { throw null; } }
- object? System.Collections.IList.this[int index] { get { throw null; } set { } }
- public abstract System.Numerics.Tensors.Tensor Clone();
- public virtual System.Numerics.Tensors.Tensor CloneEmpty() { throw null; }
- public virtual System.Numerics.Tensors.Tensor CloneEmpty(System.ReadOnlySpan dimensions) { throw null; }
- public virtual System.Numerics.Tensors.Tensor CloneEmpty() { throw null; }
- public abstract System.Numerics.Tensors.Tensor CloneEmpty(System.ReadOnlySpan dimensions);
- public static int Compare(System.Numerics.Tensors.Tensor left, System.Numerics.Tensors.Tensor right) { throw null; }
- protected virtual bool Contains(T item) { throw null; }
- protected virtual void CopyTo(T[] array, int arrayIndex) { }
- public static bool Equals(System.Numerics.Tensors.Tensor left, System.Numerics.Tensors.Tensor right) { throw null; }
- public virtual void Fill(T value) { }
- public string GetArrayString(bool includeWhitespace = true) { throw null; }
- public System.Numerics.Tensors.Tensor GetDiagonal() { throw null; }
- public System.Numerics.Tensors.Tensor GetDiagonal(int offset) { throw null; }
- public System.Numerics.Tensors.Tensor GetTriangle() { throw null; }
- public System.Numerics.Tensors.Tensor GetTriangle(int offset) { throw null; }
- public System.Numerics.Tensors.Tensor GetUpperTriangle() { throw null; }
- public System.Numerics.Tensors.Tensor GetUpperTriangle(int offset) { throw null; }
- public abstract T GetValue(int index);
- protected virtual int IndexOf(T item) { throw null; }
- public abstract System.Numerics.Tensors.Tensor Reshape(System.ReadOnlySpan dimensions);
- public abstract void SetValue(int index, T value);
- public struct Enumerator : System.Collections.Generic.IEnumerator
- {
- public T Current { get; private set; }
- object? System.Collections.IEnumerator.Current => throw null;
- public bool MoveNext() => throw null;
- public void Reset() { }
- public void Dispose() { }
- }
- public Enumerator GetEnumerator() => throw null;
- void System.Collections.Generic.ICollection.Add(T item) { }
- void System.Collections.Generic.ICollection.Clear() { }
- bool System.Collections.Generic.ICollection.Contains(T item) { throw null; }
- void System.Collections.Generic.ICollection.CopyTo(T[] array, int arrayIndex) { }
- bool System.Collections.Generic.ICollection.Remove(T item) { throw null; }
- System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { throw null; }
- int System.Collections.Generic.IList.IndexOf(T item) { throw null; }
- void System.Collections.Generic.IList.Insert(int index, T item) { }
- void System.Collections.Generic.IList.RemoveAt(int index) { }
- void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- int System.Collections.IList.Add(object? value) { throw null; }
- void System.Collections.IList.Clear() { }
- bool System.Collections.IList.Contains(object? value) { throw null; }
- int System.Collections.IList.IndexOf(object? value) { throw null; }
- void System.Collections.IList.Insert(int index, object? value) { }
- void System.Collections.IList.Remove(object? value) { }
- void System.Collections.IList.RemoveAt(int index) { }
- int System.Collections.IStructuralComparable.CompareTo(object? other, System.Collections.IComparer comparer) { throw null; }
- bool System.Collections.IStructuralEquatable.Equals(object? other, System.Collections.IEqualityComparer comparer) { throw null; }
- int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; }
- public virtual System.Numerics.Tensors.CompressedSparseTensor ToCompressedSparseTensor() { throw null; }
- public virtual System.Numerics.Tensors.DenseTensor ToDenseTensor() { throw null; }
- public virtual System.Numerics.Tensors.SparseTensor ToSparseTensor() { throw null; }
+ public static void Add(System.ReadOnlySpan x, float y, System.Span destination) { throw null; }
+ public static void Add(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { throw null; }
+ public static void AddMultiply(System.ReadOnlySpan x, float y, System.ReadOnlySpan multiplier, System.Span destination) { throw null; }
+ public static void AddMultiply(System.ReadOnlySpan x, System.ReadOnlySpan y, float multiplier, System.Span destination) { throw null; }
+ public static void AddMultiply(System.ReadOnlySpan x, System.ReadOnlySpan y, System.ReadOnlySpan multiplier, System.Span destination) { throw null; }
+ public static void Cosh(System.ReadOnlySpan x, System.Span destination) { throw null; }
+ public static void Divide(System.ReadOnlySpan x, float y, System.Span destination) { throw null; }
+ public static void Divide(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { throw null; }
+ public static void Exp(System.ReadOnlySpan x, System.Span destination) { throw null; }
+ public static void Log(System.ReadOnlySpan x, System.Span destination) { throw null; }
+ public static void Multiply(System.ReadOnlySpan x, float y, System.Span destination) { throw null; }
+ public static void Multiply(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { throw null; }
+ public static void MultiplyAdd(System.ReadOnlySpan x, float y, System.ReadOnlySpan addend, System.Span destination) { throw null; }
+ public static void MultiplyAdd(System.ReadOnlySpan x, System.ReadOnlySpan y, float addend, System.Span destination) { throw null; }
+ public static void MultiplyAdd(System.ReadOnlySpan x, System.ReadOnlySpan y, System.ReadOnlySpan addend, System.Span destination) { throw null; }
+ public static void Negate(System.ReadOnlySpan x, System.Span destination) { throw null; }
+ public static void Subtract(System.ReadOnlySpan x, float y, System.Span destination) { throw null; }
+ public static void Subtract(System.ReadOnlySpan x, System.ReadOnlySpan y, System.Span destination) { throw null; }
+ public static void Sinh(System.ReadOnlySpan x, System.Span destination) { throw null; }
+ public static void Tanh(System.ReadOnlySpan x, System.Span destination) { throw null; }
}
}
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 cabfe50e267cfb..8d1d484b33ecd4 100644
--- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj
+++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.csproj
@@ -1,4 +1,5 @@
+
$(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)
@@ -10,4 +11,5 @@
+
\ No newline at end of file
diff --git a/src/libraries/System.Numerics.Tensors/src/Properties/InternalsVisibleTo.cs b/src/libraries/System.Numerics.Tensors/src/Properties/InternalsVisibleTo.cs
deleted file mode 100644
index 2b044e474d570a..00000000000000
--- a/src/libraries/System.Numerics.Tensors/src/Properties/InternalsVisibleTo.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-// 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;
-
-[assembly: InternalsVisibleTo("System.Numerics.Tensors.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b86c4cb78549b34bab61a3b1800e23bfeb5b3ec390074041536a7e3cbd97f5f04cf0f857155a8928eaa29ebfd11cfbbad3ba70efea7bda3226c6a8d370a4cd303f714486b6ebc225985a638471e6ef571cc92a4613c00b8fa65d61ccee0cbe5f36330c9a01f4183559f1bef24cc2917c6d913e3a541333a1d05d9bed22b38cb")]
diff --git a/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx b/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx
index 57f792dde51dc2..f9f7f45078a046 100644
--- a/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx
+++ b/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx
@@ -117,52 +117,10 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- Array must contain elements.
+
+ Destination is too short.
-
- Cannot compare {0} to {1}.
-
-
- Cannot compare {0} to {1} with different dimension {2}, {3} != {4}.
-
-
- Cannot compare {0} with different dimension {1}, {2} != {3}.
-
-
- Cannot compare {0} with Rank {1} to {2} with Rank {3}.
-
-
- Cannot compute diagonal of {0} with Rank less than 2.
-
-
- Cannot compute diagonal with offset {0}.
-
-
- Tensor {0} must have at least one dimension.
-
-
- Cannot compute triangle of {0} with Rank less than 2.
-
-
- Cannot reshape array due to mismatch in lengths, currently {0} would become {1}.
-
-
- Dimensions must be positive and non-zero.
-
-
- Dimensions must contain elements.
-
-
- Length of {0} ({1}) must match product of {2} ({3}).
-
-
- The number of elements in the Tensor is greater than the available space from index to the end of the destination array.
-
-
- Only single dimensional arrays are supported for the requested action.
-
-
- The value "{0}" is not of type "{1}" and cannot be used in this generic collection.
+
+ Length of '{0}' must be same as length of '{1}'.
\ 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 521f8055a4fa61..5c188c2e0b841d 100644
--- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj
+++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj
@@ -1,30 +1,28 @@
+
$(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)
true
-
- $(NoWarn);1591
true
- Tensor class which represents and extends multi-dimensional arrays.
-
-Commonly Used Types:
-System.Numerics.Tensors.Tensor<T>
-System.Numerics.Tensors.CompressedSparseTensor<T>
-System.Numerics.Tensors.DenseTensor<T>
-System.Numerics.Tensors.SparseTensor<T>
+ Provides support for operating over tensors.
+
+ true
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayTensorExtensions.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayTensorExtensions.cs
deleted file mode 100644
index 05e12a62c990e4..00000000000000
--- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayTensorExtensions.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Numerics.Tensors
-{
- public static class ArrayTensorExtensions
- {
- ///
- /// Creates a copy of this single-dimensional array as a DenseTensor<T>
- ///
- /// Type contained in the array to copy to the DenseTensor<T>.
- /// The array to create a DenseTensor<T> from.
- /// A 1-dimensional DenseTensor<T> with the same length and content as .
- public static DenseTensor ToTensor(this T[] array)
- {
- return new DenseTensor(array);
- }
-
- ///
- /// Creates a copy of this two-dimensional array as a DenseTensor<T>
- ///
- /// Type contained in the array to copy to the DenseTensor<T>.
- /// The array to create a DenseTensor<T> from.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): row-major. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): column-major.
- /// A 2-dimensional DenseTensor<T> with the same dimensions and content as .
- public static DenseTensor ToTensor(this T[,] array, bool reverseStride = false)
- {
- return new DenseTensor(array, reverseStride);
- }
-
- ///
- /// Creates a copy of this three-dimensional array as a DenseTensor<T>
- ///
- /// Type contained in the array to copy to the DenseTensor<T>.
- /// The array to create a DenseTensor<T> from.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
- /// A 3-dimensional DenseTensor<T> with the same dimensions and content as .
- public static DenseTensor ToTensor(this T[,,] array, bool reverseStride = false)
- {
- return new DenseTensor(array, reverseStride);
- }
-
- ///
- /// Creates a copy of this n-dimensional array as a DenseTensor<T>
- ///
- /// Type contained in the array to copy to the DenseTensor<T>.
- /// The array to create a DenseTensor<T> from.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
- /// A n-dimensional DenseTensor<T> with the same dimensions and content as .
- public static DenseTensor ToTensor(this Array array, bool reverseStride = false)
- {
- return new DenseTensor(array, reverseStride);
- }
-
- ///
- /// Creates a copy of this single-dimensional array as a SparseTensor<T>
- ///
- /// Type contained in the array to copy to the SparseTensor<T>.
- /// The array to create a SparseTensor<T> from.
- /// A 1-dimensional SparseTensor<T> with the same length and content as .
- public static SparseTensor ToSparseTensor(this T[] array)
- {
- return new SparseTensor(array);
- }
-
- ///
- /// Creates a copy of this two-dimensional array as a SparseTensor<T>
- ///
- /// Type contained in the array to copy to the SparseTensor<T>.
- /// The array to create a SparseTensor<T> from.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): row-major. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): column-major.
- /// A 2-dimensional SparseTensor<T> with the same dimensions and content as .
- public static SparseTensor ToSparseTensor(this T[,] array, bool reverseStride = false)
- {
- return new SparseTensor(array, reverseStride);
- }
-
- ///
- /// Creates a copy of this three-dimensional array as a SparseTensor<T>
- ///
- /// Type contained in the array to copy to the SparseTensor<T>.
- /// The array to create a SparseTensor<T> from.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
- /// A 3-dimensional SparseTensor<T> with the same dimensions and content as .
- public static SparseTensor ToSparseTensor(this T[,,] array, bool reverseStride = false)
- {
- return new SparseTensor(array, reverseStride);
- }
-
- ///
- /// Creates a copy of this n-dimensional array as a SparseTensor<T>
- ///
- /// Type contained in the array to copy to the SparseTensor<T>.
- /// The array to create a SparseTensor<T> from.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
- /// A n-dimensional SparseTensor<T> with the same dimensions and content as .
- public static SparseTensor ToSparseTensor(this Array array, bool reverseStride = false)
- {
- return new SparseTensor(array, reverseStride);
- }
-
- ///
- /// Creates a copy of this single-dimensional array as a CompressedSparseTensor<T>
- ///
- /// Type contained in the array to copy to the CompressedSparseTensor<T>.
- /// The array to create a CompressedSparseTensor<T> from.
- /// A 1-dimensional CompressedSparseTensor<T> with the same length and content as .
- public static CompressedSparseTensor ToCompressedSparseTensor(this T[] array)
- {
- return new CompressedSparseTensor(array);
- }
-
- ///
- /// Creates a copy of this two-dimensional array as a CompressedSparseTensor<T>
- ///
- /// Type contained in the array to copy to the CompressedSparseTensor<T>.
- /// The array to create a CompressedSparseTensor<T> from.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): row-major. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): column-major.
- /// A 2-dimensional CompressedSparseTensor<T> with the same dimensions and content as .
- public static CompressedSparseTensor ToCompressedSparseTensor(this T[,] array, bool reverseStride = false)
- {
- return new CompressedSparseTensor(array, reverseStride);
- }
-
- ///
- /// Creates a copy of this three-dimensional array as a CompressedSparseTensor<T>
- ///
- /// Type contained in the array to copy to the CompressedSparseTensor<T>.
- /// The array to create a CompressedSparseTensor<T> from.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
- /// A 3-dimensional CompressedSparseTensor<T> with the same dimensions and content as .
- public static CompressedSparseTensor ToCompressedSparseTensor(this T[,,] array, bool reverseStride = false)
- {
- return new CompressedSparseTensor(array, reverseStride);
- }
-
- ///
- /// Creates a copy of this n-dimensional array as a CompressedSparseTensor<T>
- ///
- /// Type contained in the array to copy to the CompressedSparseTensor<T>.
- /// The array to create a CompressedSparseTensor<T> from.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
- /// A n-dimensional CompressedSparseTensor<T> with the same dimensions and content as .
- public static CompressedSparseTensor ToCompressedSparseTensor(this Array array, bool reverseStride = false)
- {
- return new CompressedSparseTensor(array, reverseStride);
- }
- }
-}
diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayUtilities.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayUtilities.cs
deleted file mode 100644
index 97152090dfea06..00000000000000
--- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayUtilities.cs
+++ /dev/null
@@ -1,216 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Diagnostics;
-
-namespace System.Numerics.Tensors
-{
- internal static class ArrayUtilities
- {
- public const int StackallocMax = 16;
-
- public static long GetProduct(ReadOnlySpan dimensions, int startIndex = 0)
- {
- if (dimensions.Length == 0)
- {
- return 0;
- }
-
- long product = 1;
- for (int i = startIndex; i < dimensions.Length; i++)
- {
- if (dimensions[i] < 0)
- {
- throw new ArgumentOutOfRangeException($"{nameof(dimensions)}[{i}]");
- }
-
- // we use a long which should be much larger than is ever used here,
- // but still force checked
- checked
- {
- product *= dimensions[i];
- }
- }
-
- return product;
- }
-
- public static bool IsAscending(ReadOnlySpan values)
- {
- for (int i = 1; i < values.Length; i++)
- {
- if (values[i] < values[i - 1])
- {
- return false;
- }
- }
-
- return true;
- }
-
- public static bool IsDescending(ReadOnlySpan values)
- {
- for (int i = 1; i < values.Length; i++)
- {
- if (values[i] > values[i - 1])
- {
- return false;
- }
- }
-
- return true;
- }
-
- ///
- /// Gets the set of strides that can be used to calculate the offset of n-dimensions in a 1-dimensional layout
- ///
- ///
- ///
- ///
- public static int[] GetStrides(ReadOnlySpan dimensions, bool reverseStride = false)
- {
- int[] strides = new int[dimensions.Length];
-
- int stride = 1;
- if (reverseStride)
- {
- for (int i = 0; i < strides.Length; i++)
- {
- strides[i] = stride;
- stride *= dimensions[i];
- }
- }
- else
- {
- for (int i = strides.Length - 1; i >= 0; i--)
- {
- strides[i] = stride;
- stride *= dimensions[i];
- }
- }
-
- return strides;
- }
-
- public static void SplitStrides(int[] strides, int[] splitAxes, int[] newStrides, int stridesOffset, int[] splitStrides, int splitStridesOffset)
- {
- int newStrideIndex = 0;
- for (int i = 0; i < strides.Length; i++)
- {
- int stride = strides[i];
- bool isSplit = false;
- for (int j = 0; j < splitAxes.Length; j++)
- {
- if (splitAxes[j] == i)
- {
- splitStrides[splitStridesOffset + j] = stride;
- isSplit = true;
- break;
- }
- }
-
- if (!isSplit)
- {
- newStrides[stridesOffset + newStrideIndex++] = stride;
- }
- }
- }
-
- ///
- /// Calculates the 1-d index for n-d indices in layout specified by strides.
- ///
- ///
- ///
- ///
- ///
- public static int GetIndex(int[] strides, ReadOnlySpan indices, int startFromDimension = 0)
- {
- Debug.Assert(strides.Length == indices.Length);
-
- int index = 0;
- for (int i = startFromDimension; i < indices.Length; i++)
- {
- index += strides[i] * indices[i];
- }
-
- return index;
- }
-
- ///
- /// Calculates the n-d indices from the 1-d index in a layout specified by strides
- ///
- ///
- ///
- ///
- ///
- ///
- public static void GetIndices(ReadOnlySpan strides, bool reverseStride, int index, int[] indices, int startFromDimension = 0)
- {
- Debug.Assert(reverseStride ? IsAscending(strides) : IsDescending(strides), "Index decomposition requires ordered strides");
- Debug.Assert(strides.Length == indices.Length);
-
- int remainder = index;
- for (int i = startFromDimension; i < strides.Length; i++)
- {
- // reverse the index for reverseStride so that we divide by largest stride first
- var nIndex = reverseStride ? strides.Length - 1 - i : i;
-
- var stride = strides[nIndex];
- indices[nIndex] = remainder / stride;
- remainder %= stride;
- }
- }
-
- ///
- /// Calculates the n-d indices from the 1-d index in a layout specified by strides
- ///
- ///
- ///
- ///
- ///
- ///
- public static void GetIndices(ReadOnlySpan strides, bool reverseStride, int index, Span indices, int startFromDimension = 0)
- {
- Debug.Assert(reverseStride ? IsAscending(strides) : IsDescending(strides), "Index decomposition requires ordered strides");
- Debug.Assert(strides.Length == indices.Length);
-
- int remainder = index;
- for (int i = startFromDimension; i < strides.Length; i++)
- {
- // reverse the index for reverseStride so that we divide by largest stride first
- var nIndex = reverseStride ? strides.Length - 1 - i : i;
-
- var stride = strides[nIndex];
- indices[nIndex] = remainder / stride;
- remainder %= stride;
- }
- }
-
- ///
- /// Takes an 1-d index over n-d sourceStrides and recalculates it assuming same n-d coordinates over a different n-d strides
- ///
- public static int TransformIndexByStrides(int index, int[] sourceStrides, bool sourceReverseStride, int[] transformStrides)
- {
- Debug.Assert(index >= 0);
- Debug.Assert(sourceReverseStride ? IsAscending(sourceStrides) : IsDescending(sourceStrides), "Index decomposition requires ordered strides");
- Debug.Assert(sourceStrides.Length == transformStrides.Length);
-
- int transformIndex = 0;
- int remainder = index;
-
- for (int i = 0; i < sourceStrides.Length; i++)
- {
- // reverse the index for reverseStride so that we divide by largest stride first
- var nIndex = sourceReverseStride ? sourceStrides.Length - 1 - i : i;
-
- var sourceStride = sourceStrides[nIndex];
- var transformStride = transformStrides[nIndex];
-
- transformIndex += transformStride * (remainder / sourceStride);
- remainder %= sourceStride;
- }
-
- return transformIndex;
- }
- }
-}
diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/CompressedSparseTensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/CompressedSparseTensor.cs
deleted file mode 100644
index b41915acddd5ab..00000000000000
--- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/CompressedSparseTensor.cs
+++ /dev/null
@@ -1,517 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Diagnostics;
-using System.Linq;
-
-namespace System.Numerics.Tensors
-{
- ///
- /// Represents a tensor using compressed sparse format
- /// For a two dimensional tensor this is referred to as compressed sparse row (CSR, CRS, Yale), compressed sparse column (CSC, CCS)
- ///
- /// In this format, data that is in the same value for the compressed dimension has locality
- ///
- /// In standard layout of a dense tensor, data with the same value for first dimensions has locality.
- /// As such we'll use reverseStride = false (default) to mean that the first dimension is compressed (CSR)
- /// and reverseStride = true to mean that the last dimension is compressed (CSC)
- ///
- ///
- ///
- public class CompressedSparseTensor : Tensor
- {
- private Memory values;
- private readonly Memory compressedCounts;
- private Memory indices;
-
- private int nonZeroCount;
-
- private readonly int[] nonCompressedStrides;
- private readonly int compressedDimension;
-
- private const int defaultCapacity = 64;
-
- ///
- /// Constructs a new CompressedSparseTensor of the specified dimensions and stride ordering.
- ///
- /// An span of integers that represent the size of each dimension of the CompressedSparseTensor to create.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
- public CompressedSparseTensor(ReadOnlySpan dimensions, bool reverseStride = false) : this(dimensions, defaultCapacity, reverseStride)
- { }
-
- ///
- /// Constructs a new CompressedSparseTensor of the specified dimensions, initial capacity, and stride ordering.
- ///
- /// An span of integers that represent the size of each dimension of the CompressedSparseTensor to create.
- /// The number of non-zero values this tensor can store without resizing.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
- public CompressedSparseTensor(ReadOnlySpan dimensions, int capacity, bool reverseStride = false) : base(dimensions, reverseStride)
- {
- nonZeroCount = 0;
- compressedDimension = reverseStride ? Rank - 1 : 0;
- nonCompressedStrides = (int[])strides.Clone();
- nonCompressedStrides[compressedDimension] = 0;
- var compressedDimensionLength = dimensions[compressedDimension];
- compressedCounts = new int[compressedDimensionLength + 1];
- values = new T[capacity];
- indices = new int[capacity];
- }
-
- ///
- /// Constructs a new CompressedSparseTensor of the specified dimensions, wrapping existing backing memory for the contents.
- /// Growing this CompressedSparseTensor will re-allocate the backing memory.
- ///
- /// Memory storing non-zero values to construct this tensor with.
- /// Memory storing the counts of non-zero elements at each index of the compressed dimension.
- /// Memory storing the linearized index (excluding the compressed dimension) of non-zero elements.
- /// The number of valid entries (eg: non-zero values) in and .
- /// An span of integers that represent the size of each dimension of the CompressedSparseTensor to create.
- /// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
- public CompressedSparseTensor(Memory values, Memory compressedCounts, Memory indices, int nonZeroCount, ReadOnlySpan dimensions, bool reverseStride = false) : base(dimensions, reverseStride)
- {
- compressedDimension = reverseStride ? Rank - 1 : 0;
- nonCompressedStrides = (int[])strides.Clone();
- nonCompressedStrides[compressedDimension] = 0;
- this.values = values;
- this.compressedCounts = compressedCounts;
- this.indices = indices;
- this.nonZeroCount = nonZeroCount;
- }
-
- internal CompressedSparseTensor(Array fromArray, bool reverseStride = false) : base(fromArray, reverseStride)
- {
- nonZeroCount = 0;
- compressedDimension = reverseStride ? Rank - 1 : 0;
- nonCompressedStrides = (int[])strides.Clone();
- nonCompressedStrides[compressedDimension] = 0;
- var compressedDimensionLength = dimensions[compressedDimension];
- compressedCounts = new int[compressedDimensionLength + 1];
-
- int index = 0;
- if (reverseStride)
- {
- // Array is always row-major
- var sourceStrides = ArrayUtilities.GetStrides(dimensions);
-
- foreach (T item in fromArray)
- {
- if (!item!.Equals(Zero))
- {
- var destIndex = ArrayUtilities.TransformIndexByStrides(index, sourceStrides, false, strides);
- var compressedIndex = destIndex / strides[compressedDimension];
- var nonCompressedIndex = destIndex % strides[compressedDimension];
-
- SetAt(item, compressedIndex, nonCompressedIndex);
- }
-
- index++;
- }
- }
- else
- {
- foreach (T item in fromArray)
- {
- if (!item!.Equals(Zero))
- {
- var compressedIndex = index / strides[compressedDimension];
- var nonCompressedIndex = index % strides[compressedDimension];
-
- SetAt(item, compressedIndex, nonCompressedIndex);
- }
-
- index++;
- }
- }
- }
-
- ///
- /// Obtains the value at the specified indices
- ///
- /// A span of integers that represent the indices specifying the position of the element to get.
- /// The value at the specified position in this Tensor.
- public override T this[ReadOnlySpan indices]
- {
- get
- {
- var compressedIndex = indices[compressedDimension];
- var nonCompressedIndex = ArrayUtilities.GetIndex(nonCompressedStrides, indices);
-
-
- if (TryFindIndex(compressedIndex, nonCompressedIndex, out int valueIndex))
- {
- return values.Span[valueIndex];
- }
-
- return Zero;
- }
-
- set
- {
- var compressedIndex = indices[compressedDimension];
- var nonCompressedIndex = ArrayUtilities.GetIndex(nonCompressedStrides, indices);
-
- SetAt(value, compressedIndex, nonCompressedIndex);
- }
- }
-
- ///
- /// Gets the value at the specified index, where index is lineraized as a dot product between indices and strides.
- ///
- /// An integer index computed as a dot-product of indices.
- /// The value at the specified position in this Tensor.
- public override T GetValue(int index)
- {
- var compressedDimensionStride = strides[compressedDimension];
- Debug.Assert(compressedDimensionStride == strides.Max());
-
- var compressedIndex = index / compressedDimensionStride;
- var nonCompressedIndex = index % compressedDimensionStride;
-
-
- if (TryFindIndex(compressedIndex, nonCompressedIndex, out int valueIndex))
- {
- return values.Span[valueIndex];
- }
-
- return Zero;
- }
-
- ///
- /// Sets the value at the specified index, where index is a linearized version of n-dimension indices using strides.
- ///
- /// An integer index computed as a dot-product of indices.
- /// The new value to set at the specified position in this Tensor.
- public override void SetValue(int index, T value)
- {
- var compressedDimensionStride = strides[compressedDimension];
- Debug.Assert(compressedDimensionStride == strides.Max());
-
- var compressedIndex = index / compressedDimensionStride;
- var nonCompressedIndex = index % compressedDimensionStride;
-
- SetAt(value, compressedIndex, nonCompressedIndex);
-
- }
-
- ///
- /// Gets the number of non-zero values this tensor can store without resizing.
- ///
- public int Capacity => values.Length;
-
- ///
- /// Get's the number on non-zero values currently being stored in this tensor.
- ///
- public int NonZeroCount => nonZeroCount;
-
- ///
- /// Memory storing non-zero values.
- ///
- public Memory Values => values;
-
- ///
- /// Memory storing the counts of non-zero elements at each index of the compressed dimension.
- ///
- public Memory CompressedCounts => compressedCounts;
-
- ///
- /// Memory storing the linearized index (excluding the compressed dimension) of non-zero elements.
- ///
- public Memory Indices => indices;
-
- private void EnsureCapacity(int min, int allocateIndex = -1)
- {
- if (values.Length < min)
- {
- var newCapacity = values.Length == 0 ? defaultCapacity : values.Length * 2;
-
- if (newCapacity > Length)
- {
- newCapacity = (int)Length;
- }
-
- if (newCapacity < min)
- {
- newCapacity = min;
- }
-
- Memory newValues = new T[newCapacity];
- Memory newIndices = new int[newCapacity];
-
- if (nonZeroCount > 0)
- {
- if (allocateIndex == -1)
- {
- var valuesSpan = values.Span.Slice(0, nonZeroCount);
- var indicesSpan = indices.Span.Slice(0, nonZeroCount);
-
- valuesSpan.CopyTo(newValues.Span);
- indicesSpan.CopyTo(newIndices.Span);
- }
- else
- {
- Debug.Assert(allocateIndex <= nonZeroCount);
- // leave a gap at allocateIndex
-
- // copy range before allocateIndex
- if (allocateIndex > 0)
- {
- var valuesSpan = values.Span.Slice(0, allocateIndex);
- var indicesSpan = indices.Span.Slice(0, allocateIndex);
-
- valuesSpan.CopyTo(newValues.Span);
- indicesSpan.CopyTo(newIndices.Span);
- }
-
- if (allocateIndex < nonZeroCount)
- {
- var valuesSpan = values.Span.Slice(allocateIndex, nonZeroCount - allocateIndex);
- var indicesSpan = indices.Span.Slice(allocateIndex, nonZeroCount - allocateIndex);
-
- var newValuesSpan = newValues.Span.Slice(allocateIndex + 1, nonZeroCount - allocateIndex);
- var newIndicesSpan = newIndices.Span.Slice(allocateIndex + 1, nonZeroCount - allocateIndex);
-
- valuesSpan.CopyTo(newValuesSpan);
- indicesSpan.CopyTo(newIndicesSpan);
- }
- }
- }
-
- values = newValues;
- indices = newIndices;
- }
- }
-
- private void InsertAt(int valueIndex, T value, int compressedIndex, int nonCompressedIndex)
- {
- Debug.Assert(valueIndex <= nonZeroCount);
- Debug.Assert(compressedIndex < compressedCounts.Length - 1);
-
- if (values.Length <= valueIndex)
- {
- // allocate a new array, leaving a gap
- EnsureCapacity(valueIndex + 1, valueIndex);
- }
- else if (nonZeroCount != valueIndex)
- {
- // shift values to make a gap
- values.Span.Slice(valueIndex, nonZeroCount - valueIndex).CopyTo(values.Span.Slice(valueIndex + 1));
- indices.Span.Slice(valueIndex, nonZeroCount - valueIndex).CopyTo(indices.Span.Slice(valueIndex + 1));
- }
-
- values.Span[valueIndex] = value;
- indices.Span[valueIndex] = nonCompressedIndex;
-
- var compressedCountsSpan = compressedCounts.Span.Slice(compressedIndex + 1);
- for (int i = 0; i < compressedCountsSpan.Length; i++)
- {
- compressedCountsSpan[i]++;
- }
- nonZeroCount++;
- }
-
- private void RemoveAt(int valueIndex, int compressedIndex)
- {
- Debug.Assert(valueIndex < nonZeroCount);
- Debug.Assert(compressedIndex < compressedCounts.Length - 1);
-
- // shift values to close the gap
- values.Span.Slice(valueIndex + 1, nonZeroCount - valueIndex - 1).CopyTo(values.Span.Slice(valueIndex));
- indices.Span.Slice(valueIndex + 1, nonZeroCount - valueIndex - 1).CopyTo(indices.Span.Slice(valueIndex));
-
- var compressedCountsSpan = compressedCounts.Span.Slice(compressedIndex + 1);
- for (int i = 0; i < compressedCountsSpan.Length; i++)
- {
- compressedCountsSpan[i]--;
- }
- nonZeroCount--;
- }
-
- private void SetAt(T value, int compressedIndex, int nonCompressedIndex)
- {
- bool isZero = value!.Equals(Zero);
-
- if (TryFindIndex(compressedIndex, nonCompressedIndex, out int valueIndex))
- {
- if (isZero)
- {
- RemoveAt(valueIndex, compressedIndex);
- }
- else
- {
- values.Span[valueIndex] = value;
- indices.Span[valueIndex] = nonCompressedIndex;
- }
- }
- else if (!isZero)
- {
- InsertAt(valueIndex, value, compressedIndex, nonCompressedIndex);
- }
- }
-
- ///
- /// Trys to find the place to store a value
- ///
- ///
- ///
- ///
- /// True if element is found at specific index, false if no specific index is found and insertion point is returned
- private bool TryFindIndex(int compressedIndex, int nonCompressedIndex, out int valueIndex)
- {
- if (nonZeroCount == 0)
- {
- valueIndex = 0;
- return false;
- }
-
- Debug.Assert(compressedIndex < compressedCounts.Length - 1);
-
- var compressedCountsSpan = compressedCounts.Span;
- var lowerValueIndex = compressedCountsSpan[compressedIndex];
- var upperValueIndex = compressedCountsSpan[compressedIndex + 1];
- var indicesSpan = indices.Span;
-
- // could be a faster search
- for (valueIndex = lowerValueIndex; valueIndex < upperValueIndex; valueIndex++)
- {
- if (indicesSpan[valueIndex] == nonCompressedIndex)
- {
- return true;
- }
- }
-
- return false;
- }
-
- ///
- /// Creates a shallow copy of this tensor, with new backing storage.
- ///
- /// A shallow copy of this tensor.
- public override Tensor Clone()
- {
- return new CompressedSparseTensor(values.ToArray(), compressedCounts.ToArray(), indices.ToArray(), nonZeroCount, dimensions, IsReversedStride);
- }
-
- ///
- /// Creates a new Tensor of a different type with the specified dimensions and the same layout as this tensor with elements initialized to their default value.
- ///
- /// Type contained in the returned Tensor.
- /// An span of integers that represent the size of each dimension of the CompressedSparseTensor to create.
- /// A new tensor with the same layout as this tensor but different type and dimensions.
- public override Tensor CloneEmpty(ReadOnlySpan dimensions)
- {
- return new CompressedSparseTensor(dimensions, IsReversedStride);
- }
-
- ///
- /// Reshapes the current tensor to new dimensions. Unlike other Tensor implementations, CompressedSparseTensor<T> must allocate new backing storage to represent a reshaped Tensor.
- ///
- /// An span of integers that represent the size of each dimension of the CompressedSparseTensor to create.
- /// A new tensor that reinterprets the content of this tensor to new dimensions (assuming the same linear index for each element).
- public override Tensor Reshape(ReadOnlySpan dimensions)
- {
- // reshape currently has shallow semantics which are not compatible with the backing storage for CompressedSparseTensor
- // which bakes in information about dimensions (compressedCounts and indices)
-
- var newCompressedDimension = IsReversedStride ? dimensions.Length - 1 : 0;
- var newCompressedDimensionLength = dimensions[newCompressedDimension];
- var newCompressedDimensionStride = (int)(Length / newCompressedDimensionLength);
-
- var newValues = (T[])values.ToArray();
- var newCompressedCounts = new int[newCompressedDimensionLength + 1];
- var newIndices = new int[indices.Length];
-
- var compressedIndex = 0;
-
- var compressedCountsSpan = compressedCounts.Span;
- var indicesSpan = indices.Span.Slice(0, nonZeroCount);
- for (int valueIndex = 0; valueIndex < indicesSpan.Length; valueIndex++)
- {
- while (valueIndex >= compressedCountsSpan[compressedIndex + 1])
- {
- compressedIndex++;
- Debug.Assert(compressedIndex < compressedCounts.Length);
- }
-
- var currentIndex = indicesSpan[valueIndex] + compressedIndex * strides[compressedDimension];
-
- newIndices[valueIndex] = currentIndex % newCompressedDimensionStride;
-
- var newCompressedIndex = currentIndex / newCompressedDimensionStride;
- newCompressedCounts[newCompressedIndex + 1] = valueIndex + 1;
- }
-
- return new CompressedSparseTensor(newValues, newCompressedCounts, newIndices, nonZeroCount, dimensions, IsReversedStride);
- }
-
- ///