From 0d2cb5ea82bcaa3352a514bae0777fe7753abbbf Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 10 Feb 2026 15:16:09 +0000
Subject: [PATCH 1/6] Initial plan


From 3bc90c84c9008591261d33cbcc88a5c5b9610f23 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 10 Feb 2026 15:43:51 +0000
Subject: [PATCH 2/6] Fix SequenceEqual to compare only logical elements for
 non-dense tensor spans

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
---
 .../System/Numerics/Tensors/netcore/Tensor.cs | 35 ++++++++++++++-----
 .../tests/TensorTests.cs                      | 28 +++++++++++++++
 2 files changed, 55 insertions(+), 8 deletions(-)

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 c64250c0151164..4629bf6d35795a 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
@@ -1684,10 +1684,7 @@ public static ref readonly TensorSpan<T> ReverseDimension<T>(scoped in ReadOnlyT
         public static bool SequenceEqual<T>(this scoped in TensorSpan<T> tensor, scoped in ReadOnlyTensorSpan<T> other)
             where T : IEquatable<T>?
         {
-            return tensor.FlattenedLength == other.FlattenedLength
-                && tensor._shape.LinearLength == other._shape.LinearLength
-                && tensor.Lengths.SequenceEqual(other.Lengths)
-                && MemoryMarshal.CreateReadOnlySpan(in tensor.GetPinnableReference(), (int)tensor._shape.LinearLength).SequenceEqual(MemoryMarshal.CreateReadOnlySpan(in other.GetPinnableReference(), (int)other._shape.LinearLength));
+            return ((ReadOnlyTensorSpan<T>)tensor).SequenceEqual(other);
         }
 
         /// <summary>
@@ -1696,10 +1693,32 @@ public static bool SequenceEqual<T>(this scoped in TensorSpan<T> tensor, scoped
         public static bool SequenceEqual<T>(this scoped in ReadOnlyTensorSpan<T> tensor, scoped in ReadOnlyTensorSpan<T> other)
             where T : IEquatable<T>?
         {
-            return tensor.FlattenedLength == other.FlattenedLength
-                && tensor._shape.LinearLength == other._shape.LinearLength
-                && tensor.Lengths.SequenceEqual(other.Lengths)
-                && MemoryMarshal.CreateReadOnlySpan(in tensor.GetPinnableReference(), (int)tensor._shape.LinearLength).SequenceEqual(MemoryMarshal.CreateReadOnlySpan(in other.GetPinnableReference(), (int)other._shape.LinearLength));
+            if (tensor.FlattenedLength != other.FlattenedLength
+                || !tensor.Lengths.SequenceEqual(other.Lengths))
+            {
+                return false;
+            }
+
+            if (tensor.IsDense && other.IsDense)
+            {
+                return MemoryMarshal.CreateReadOnlySpan(in tensor.GetPinnableReference(), (int)tensor._shape.LinearLength).SequenceEqual(MemoryMarshal.CreateReadOnlySpan(in other.GetPinnableReference(), (int)other._shape.LinearLength));
+            }
+
+            ReadOnlyTensorSpan<T>.Enumerator enumerator1 = tensor.GetEnumerator();
+            ReadOnlyTensorSpan<T>.Enumerator enumerator2 = other.GetEnumerator();
+
+            while (enumerator1.MoveNext())
+            {
+                bool moved = enumerator2.MoveNext();
+                Debug.Assert(moved);
+
+                if (!EqualityComparer<T>.Default.Equals(enumerator1.Current, enumerator2.Current))
+                {
+                    return false;
+                }
+            }
+
+            return true;
         }
         #endregion
 
diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
index 8aeaddc990dcda..9f740919230e22 100644
--- a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
+++ b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
@@ -714,6 +714,34 @@ public static void TensorCosineSimilarityTests()
         //    Assert.Throws<Exception>(() => Tensor.SequenceEqual(t0, t1));
         //}
 
+        [Fact]
+        public static void TensorSequenceEqualNonDenseTests()
+        {
+            int[] d1 = [10, 20, 99, 99, 30, 40, 99, 99];
+            int[] d2 = [10, 20, 77, 77, 30, 40, 77, 77];
+
+            var ts1 = new ReadOnlyTensorSpan<int>(d1, [2, 2], [4, 1]);
+            var ts2 = new ReadOnlyTensorSpan<int>(d2, [2, 2], [4, 1]);
+
+            Assert.False(ts1.IsDense);
+            Assert.False(ts2.IsDense);
+            Assert.True(ts1.SequenceEqual(ts2));
+
+            int[] d3 = [10, 20, 99, 99, 30, 41, 99, 99];
+            var ts3 = new ReadOnlyTensorSpan<int>(d3, [2, 2], [4, 1]);
+            Assert.False(ts1.SequenceEqual(ts3));
+
+            int[] d4 = [10, 20, 30, 40];
+            var ts4 = new ReadOnlyTensorSpan<int>(d4, [2, 2], [2, 1]);
+            Assert.True(ts4.IsDense);
+            Assert.True(ts1.SequenceEqual(ts4));
+            Assert.True(ts4.SequenceEqual(ts1));
+
+            var tspan1 = new TensorSpan<int>(d1, [2, 2], [4, 1]);
+            var tspan2 = new ReadOnlyTensorSpan<int>(d2, [2, 2], [4, 1]);
+            Assert.True(tspan1.SequenceEqual(tspan2));
+        }
+
         [Fact]
         public static void TensorMultiplyTests()
         {

From 99ba36432ffe8187970c00eac6717d202aef8e7a Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 10 Feb 2026 17:09:09 +0000
Subject: [PATCH 3/6] Fix non-dense span handling in Fill*, Resize*, IndexOf*
 methods and add tests

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
---
 .../System/Numerics/Tensors/netcore/Tensor.cs | 168 +++++++++++++++---
 .../tests/TensorTests.cs                      | 143 +++++++++++++++
 2 files changed, 284 insertions(+), 27 deletions(-)

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 4629bf6d35795a..51eca83bb44bdc 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
@@ -347,14 +347,29 @@ public static Tensor<T> CreateFromShapeUninitialized<T>(scoped ReadOnlySpan<nint
         /// <returns></returns>
         public static ref readonly TensorSpan<T> FillGaussianNormalDistribution<T>(in TensorSpan<T> destination, Random? random = null) where T : IFloatingPoint<T>
         {
-            Span<T> span = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape.LinearLength);
             random ??= Random.Shared;
 
-            for (int i = 0; i < span.Length; i++)
+            if (destination.IsDense)
             {
-                double u1 = 1.0 - random.NextDouble();
-                double u2 = 1.0 - random.NextDouble();
-                span[i] = T.CreateChecked(Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2));
+                Span<T> span = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength);
+
+                for (int i = 0; i < span.Length; i++)
+                {
+                    double u1 = 1.0 - random.NextDouble();
+                    double u2 = 1.0 - random.NextDouble();
+                    span[i] = T.CreateChecked(Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2));
+                }
+            }
+            else
+            {
+                TensorSpan<T>.Enumerator enumerator = destination.GetEnumerator();
+
+                while (enumerator.MoveNext())
+                {
+                    double u1 = 1.0 - random.NextDouble();
+                    double u2 = 1.0 - random.NextDouble();
+                    enumerator.Current = T.CreateChecked(Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2));
+                }
             }
 
             return ref destination;
@@ -370,10 +385,23 @@ public static ref readonly TensorSpan<T> FillGaussianNormalDistribution<T>(in Te
         /// <returns></returns>
         public static ref readonly TensorSpan<T> FillUniformDistribution<T>(in TensorSpan<T> destination, Random? random = null) where T : IFloatingPoint<T>
         {
-            Span<T> 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());
+
+            if (destination.IsDense)
+            {
+                Span<T> span = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength);
+                for (int i = 0; i < span.Length; i++)
+                    span[i] = T.CreateChecked(random.NextDouble());
+            }
+            else
+            {
+                TensorSpan<T>.Enumerator enumerator = destination.GetEnumerator();
+
+                while (enumerator.MoveNext())
+                {
+                    enumerator.Current = T.CreateChecked(random.NextDouble());
+                }
+            }
 
             return ref destination;
         }
@@ -1549,12 +1577,29 @@ public static Tensor<T> Resize<T>(Tensor<T> tensor, ReadOnlySpan<nint> lengths)
             nint newSize = TensorPrimitives.Product(lengths);
             T[] values = tensor.IsPinned ? GC.AllocateArray<T>((int)newSize) : (new T[newSize]);
             Tensor<T> output = Create(values, lengths, []);
-            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref tensor.AsTensorSpan()._reference, tensor._start), tensor._values.Length - tensor._start);
-            Span<T> ospan = MemoryMarshal.CreateSpan(ref output.AsTensorSpan()._reference, (int)output.FlattenedLength);
-            if (newSize >= span.Length)
-                span.CopyTo(ospan);
+
+            if (tensor.IsDense)
+            {
+                ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref tensor.AsTensorSpan()._reference, tensor._start), tensor._values.Length - tensor._start);
+                Span<T> ospan = MemoryMarshal.CreateSpan(ref output.AsTensorSpan()._reference, (int)output.FlattenedLength);
+                if (newSize >= span.Length)
+                    span.CopyTo(ospan);
+                else
+                    span.Slice(0, ospan.Length).CopyTo(ospan);
+            }
             else
-                span.Slice(0, ospan.Length).CopyTo(ospan);
+            {
+                nint copyLength = Math.Min(tensor.FlattenedLength, newSize);
+                ReadOnlyTensorSpan<T>.Enumerator enumerator = tensor.AsReadOnlyTensorSpan().GetEnumerator();
+                Span<T> ospan = MemoryMarshal.CreateSpan(ref output.AsTensorSpan()._reference, (int)output.FlattenedLength);
+
+                for (nint i = 0; i < copyLength; i++)
+                {
+                    bool moved = enumerator.MoveNext();
+                    Debug.Assert(moved);
+                    ospan[(int)i] = enumerator.Current;
+                }
+            }
 
             return output;
         }
@@ -1589,12 +1634,29 @@ public static void ResizeTo<T>(scoped in TensorSpan<T> tensor, in TensorSpan<T>
         /// <param name="destination">Destination <see cref="TensorSpan{T}"/> with the desired new shape.</param>
         public static void ResizeTo<T>(scoped in ReadOnlyTensorSpan<T> tensor, in TensorSpan<T> destination)
         {
-            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref tensor._reference, (int)tensor._shape.LinearLength);
-            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape.LinearLength);
-            if (ospan.Length >= span.Length)
-                span.CopyTo(ospan);
+            if (tensor.IsDense && destination.IsDense)
+            {
+                ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref tensor._reference, (int)tensor.FlattenedLength);
+                Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength);
+                if (ospan.Length >= span.Length)
+                    span.CopyTo(ospan);
+                else
+                    span.Slice(0, ospan.Length).CopyTo(ospan);
+            }
             else
-                span.Slice(0, ospan.Length).CopyTo(ospan);
+            {
+                nint copyLength = Math.Min(tensor.FlattenedLength, destination.FlattenedLength);
+                ReadOnlyTensorSpan<T>.Enumerator srcEnumerator = tensor.GetEnumerator();
+                TensorSpan<T>.Enumerator dstEnumerator = destination.GetEnumerator();
+
+                for (nint i = 0; i < copyLength; i++)
+                {
+                    bool srcMoved = srcEnumerator.MoveNext();
+                    bool dstMoved = dstEnumerator.MoveNext();
+                    Debug.Assert(srcMoved && dstMoved);
+                    dstEnumerator.Current = srcEnumerator.Current;
+                }
+            }
         }
         #endregion
 
@@ -1701,7 +1763,7 @@ public static bool SequenceEqual<T>(this scoped in ReadOnlyTensorSpan<T> tensor,
 
             if (tensor.IsDense && other.IsDense)
             {
-                return MemoryMarshal.CreateReadOnlySpan(in tensor.GetPinnableReference(), (int)tensor._shape.LinearLength).SequenceEqual(MemoryMarshal.CreateReadOnlySpan(in other.GetPinnableReference(), (int)other._shape.LinearLength));
+                return MemoryMarshal.CreateReadOnlySpan(in tensor.GetPinnableReference(), (int)tensor.FlattenedLength).SequenceEqual(MemoryMarshal.CreateReadOnlySpan(in other.GetPinnableReference(), (int)other.FlattenedLength));
             }
 
             ReadOnlyTensorSpan<T>.Enumerator enumerator1 = tensor.GetEnumerator();
@@ -3547,8 +3609,21 @@ public static ref readonly TensorSpan<int> ILogB<T>(scoped in ReadOnlyTensorSpan
         public static nint IndexOfMax<T>(scoped in ReadOnlyTensorSpan<T> x)
             where T : INumber<T>
         {
-            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape.LinearLength);
-            return TensorPrimitives.IndexOfMax(span);
+            if (x.IsDense)
+            {
+                ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x.FlattenedLength);
+                return TensorPrimitives.IndexOfMax(span);
+            }
+
+            return IndexOfMaxFallback(x);
+        }
+
+        private static nint IndexOfMaxFallback<T>(scoped in ReadOnlyTensorSpan<T> x)
+            where T : INumber<T>
+        {
+            T[] flat = new T[x.FlattenedLength];
+            x.FlattenTo(flat);
+            return TensorPrimitives.IndexOfMax<T>(flat);
         }
 
         #endregion
@@ -3559,8 +3634,21 @@ public static nint IndexOfMax<T>(scoped in ReadOnlyTensorSpan<T> x)
         public static nint IndexOfMaxMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
             where T : INumber<T>
         {
-            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape.LinearLength);
-            return TensorPrimitives.IndexOfMaxMagnitude(span);
+            if (x.IsDense)
+            {
+                ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x.FlattenedLength);
+                return TensorPrimitives.IndexOfMaxMagnitude(span);
+            }
+
+            return IndexOfMaxMagnitudeFallback(x);
+        }
+
+        private static nint IndexOfMaxMagnitudeFallback<T>(scoped in ReadOnlyTensorSpan<T> x)
+            where T : INumber<T>
+        {
+            T[] flat = new T[x.FlattenedLength];
+            x.FlattenTo(flat);
+            return TensorPrimitives.IndexOfMaxMagnitude<T>(flat);
         }
         #endregion
 
@@ -3570,8 +3658,21 @@ public static nint IndexOfMaxMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
         public static nint IndexOfMin<T>(scoped in ReadOnlyTensorSpan<T> x)
             where T : INumber<T>
         {
-            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape.LinearLength);
-            return TensorPrimitives.IndexOfMin(span);
+            if (x.IsDense)
+            {
+                ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x.FlattenedLength);
+                return TensorPrimitives.IndexOfMin(span);
+            }
+
+            return IndexOfMinFallback(x);
+        }
+
+        private static nint IndexOfMinFallback<T>(scoped in ReadOnlyTensorSpan<T> x)
+            where T : INumber<T>
+        {
+            T[] flat = new T[x.FlattenedLength];
+            x.FlattenTo(flat);
+            return TensorPrimitives.IndexOfMin<T>(flat);
         }
         #endregion
 
@@ -3583,8 +3684,21 @@ public static nint IndexOfMin<T>(scoped in ReadOnlyTensorSpan<T> x)
         public static nint IndexOfMinMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
             where T : INumber<T>
         {
-            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape.LinearLength);
-            return TensorPrimitives.IndexOfMinMagnitude(span);
+            if (x.IsDense)
+            {
+                ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x.FlattenedLength);
+                return TensorPrimitives.IndexOfMinMagnitude(span);
+            }
+
+            return IndexOfMinMagnitudeFallback(x);
+        }
+
+        private static nint IndexOfMinMagnitudeFallback<T>(scoped in ReadOnlyTensorSpan<T> x)
+            where T : INumber<T>
+        {
+            T[] flat = new T[x.FlattenedLength];
+            x.FlattenTo(flat);
+            return TensorPrimitives.IndexOfMinMagnitude<T>(flat);
         }
         #endregion
 
diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
index 9f740919230e22..1293b931d4f357 100644
--- a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
+++ b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
@@ -742,6 +742,149 @@ public static void TensorSequenceEqualNonDenseTests()
             Assert.True(tspan1.SequenceEqual(tspan2));
         }
 
+        [Fact]
+        public static void TensorFillGaussianNormalDistributionNonDenseTests()
+        {
+            double[] data = new double[8];
+            var ts = new TensorSpan<double>(data, [2, 2], [4, 1]);
+            Assert.False(ts.IsDense);
+
+            Tensor.FillGaussianNormalDistribution(ts, new Random(42));
+
+            foreach (double val in ts)
+            {
+                Assert.NotEqual(0.0, val);
+            }
+
+            Assert.Equal(0.0, data[2]);
+            Assert.Equal(0.0, data[3]);
+            Assert.Equal(0.0, data[6]);
+            Assert.Equal(0.0, data[7]);
+        }
+
+        [Fact]
+        public static void TensorFillUniformDistributionNonDenseTests()
+        {
+            double[] data = new double[8];
+            var ts = new TensorSpan<double>(data, [2, 2], [4, 1]);
+            Assert.False(ts.IsDense);
+
+            Tensor.FillUniformDistribution(ts, new Random(42));
+
+            foreach (double val in ts)
+            {
+                Assert.InRange(val, 0.0, 1.0);
+                Assert.NotEqual(0.0, val);
+            }
+
+            Assert.Equal(0.0, data[2]);
+            Assert.Equal(0.0, data[3]);
+            Assert.Equal(0.0, data[6]);
+            Assert.Equal(0.0, data[7]);
+        }
+
+        [Fact]
+        public static void TensorIndexOfMaxNonDenseTests()
+        {
+            int[] data = [1, 50, 99, 99, 3, 2, 99, 99];
+            var ts = new ReadOnlyTensorSpan<int>(data, [2, 2], [4, 1]);
+            Assert.False(ts.IsDense);
+
+            nint idx = Tensor.IndexOfMax(ts);
+            Assert.Equal(1, idx);
+        }
+
+        [Fact]
+        public static void TensorIndexOfMinNonDenseTests()
+        {
+            int[] data = [5, 50, 99, 99, 1, 2, 99, 99];
+            var ts = new ReadOnlyTensorSpan<int>(data, [2, 2], [4, 1]);
+            Assert.False(ts.IsDense);
+
+            nint idx = Tensor.IndexOfMin(ts);
+            Assert.Equal(2, idx);
+        }
+
+        [Fact]
+        public static void TensorIndexOfMaxMagnitudeNonDenseTests()
+        {
+            int[] data = [1, -50, 99, 99, 3, 2, 99, 99];
+            var ts = new ReadOnlyTensorSpan<int>(data, [2, 2], [4, 1]);
+            Assert.False(ts.IsDense);
+
+            nint idx = Tensor.IndexOfMaxMagnitude(ts);
+            Assert.Equal(1, idx);
+        }
+
+        [Fact]
+        public static void TensorIndexOfMinMagnitudeNonDenseTests()
+        {
+            int[] data = [5, 50, 99, 99, 1, -2, 99, 99];
+            var ts = new ReadOnlyTensorSpan<int>(data, [2, 2], [4, 1]);
+            Assert.False(ts.IsDense);
+
+            nint idx = Tensor.IndexOfMinMagnitude(ts);
+            Assert.Equal(2, idx);
+        }
+
+        [Fact]
+        public static void TensorResizeToNonDenseSourceTests()
+        {
+            int[] srcData = [10, 20, 99, 99, 30, 40, 99, 99];
+            var src = new ReadOnlyTensorSpan<int>(srcData, [2, 2], [4, 1]);
+            Assert.False(src.IsDense);
+
+            int[] dstData = new int[6];
+            var dst = new TensorSpan<int>(dstData, [6], [1]);
+            Assert.True(dst.IsDense);
+
+            Tensor.ResizeTo(src, dst);
+
+            Assert.Equal(10, dstData[0]);
+            Assert.Equal(20, dstData[1]);
+            Assert.Equal(30, dstData[2]);
+            Assert.Equal(40, dstData[3]);
+            Assert.Equal(0, dstData[4]);
+            Assert.Equal(0, dstData[5]);
+        }
+
+        [Fact]
+        public static void TensorResizeToNonDenseDestinationTests()
+        {
+            int[] srcData = [10, 20, 30, 40, 50, 60];
+            var src = new ReadOnlyTensorSpan<int>(srcData, [6], [1]);
+            Assert.True(src.IsDense);
+
+            int[] dstData = new int[8];
+            var dst = new TensorSpan<int>(dstData, [2, 2], [4, 1]);
+            Assert.False(dst.IsDense);
+
+            Tensor.ResizeTo(src, dst);
+
+            Assert.Equal(10, dstData[0]);
+            Assert.Equal(20, dstData[1]);
+            Assert.Equal(0, dstData[2]);
+            Assert.Equal(0, dstData[3]);
+            Assert.Equal(30, dstData[4]);
+            Assert.Equal(40, dstData[5]);
+            Assert.Equal(0, dstData[6]);
+            Assert.Equal(0, dstData[7]);
+        }
+
+        [Fact]
+        public static void TensorResizeNonDenseTests()
+        {
+            Tensor<int> tensor = Tensor.Create([10, 20, 30, 40, 50, 60], [2, 3]);
+            Tensor<int> sliced = tensor.Slice(0..2, 0..2);
+            Assert.False(sliced.IsDense);
+
+            Tensor<int> resized = Tensor.Resize(sliced, [3]);
+            Assert.Equal(3, resized.FlattenedLength);
+            Assert.Equal(10, resized[0]);
+            Assert.Equal(20, resized[1]);
+            Assert.Equal(40, resized[2]);
+        }
+
         [Fact]
         public static void TensorMultiplyTests()
         {

From 18f33d96c4254b7ffe283b566f4cdd961916b64b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 10 Feb 2026 18:39:23 +0000
Subject: [PATCH 4/6] Add braces to all one-line bodies and rewrite tests as
 comprehensive theories

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
---
 .../System/Numerics/Tensors/netcore/Tensor.cs |  10 +
 .../tests/TensorTests.cs                      | 379 ++++++++++++++----
 2 files changed, 307 insertions(+), 82 deletions(-)

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 51eca83bb44bdc..c5049cb8b93a19 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
@@ -391,7 +391,9 @@ public static ref readonly TensorSpan<T> FillUniformDistribution<T>(in TensorSpa
             {
                 Span<T> span = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength);
                 for (int i = 0; i < span.Length; i++)
+                {
                     span[i] = T.CreateChecked(random.NextDouble());
+                }
             }
             else
             {
@@ -1583,9 +1585,13 @@ public static Tensor<T> Resize<T>(Tensor<T> tensor, ReadOnlySpan<nint> lengths)
                 ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref tensor.AsTensorSpan()._reference, tensor._start), tensor._values.Length - tensor._start);
                 Span<T> ospan = MemoryMarshal.CreateSpan(ref output.AsTensorSpan()._reference, (int)output.FlattenedLength);
                 if (newSize >= span.Length)
+                {
                     span.CopyTo(ospan);
+                }
                 else
+                {
                     span.Slice(0, ospan.Length).CopyTo(ospan);
+                }
             }
             else
             {
@@ -1639,9 +1645,13 @@ public static void ResizeTo<T>(scoped in ReadOnlyTensorSpan<T> tensor, in Tensor
                 ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref tensor._reference, (int)tensor.FlattenedLength);
                 Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength);
                 if (ospan.Length >= span.Length)
+                {
                     span.CopyTo(ospan);
+                }
                 else
+                {
                     span.Slice(0, ospan.Length).CopyTo(ospan);
+                }
             }
             else
             {
diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
index 1293b931d4f357..7d5ae8d08a975c 100644
--- a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
+++ b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
@@ -714,166 +714,367 @@ public static void TensorCosineSimilarityTests()
         //    Assert.Throws<Exception>(() => Tensor.SequenceEqual(t0, t1));
         //}
 
-        [Fact]
-        public static void TensorSequenceEqualNonDenseTests()
-        {
-            int[] d1 = [10, 20, 99, 99, 30, 40, 99, 99];
-            int[] d2 = [10, 20, 77, 77, 30, 40, 77, 77];
-
-            var ts1 = new ReadOnlyTensorSpan<int>(d1, [2, 2], [4, 1]);
-            var ts2 = new ReadOnlyTensorSpan<int>(d2, [2, 2], [4, 1]);
-
+        /// <summary>
+        /// Provides test cases of (dataArray, shape, strides) for creating non-dense tensor spans.
+        /// Each case has known logical elements that differ from the raw buffer layout.
+        /// </summary>
+        public static IEnumerable<object[]> NonDenseTensorData()
+        {
+            // 2x2 from 1D array with stride gap: logical elements are [10, 20, 30, 40]
+            yield return new object[] { new int[] { 10, 20, 99, 99, 30, 40, 99, 99 }, new nint[] { 2, 2 }, new nint[] { 4, 1 }, new int[] { 10, 20, 30, 40 } };
+            // 2x3 from 1D array with stride gap: logical elements are [1, 2, 3, 4, 5, 6]
+            yield return new object[] { new int[] { 1, 2, 3, 99, 4, 5, 6, 99 }, new nint[] { 2, 3 }, new nint[] { 4, 1 }, new int[] { 1, 2, 3, 4, 5, 6 } };
+            // 3x2 from 1D array with stride gap: logical elements are [1, 2, 3, 4, 5, 6]
+            yield return new object[] { new int[] { 1, 2, 99, 3, 4, 99, 5, 6, 99 }, new nint[] { 3, 2 }, new nint[] { 3, 1 }, new int[] { 1, 2, 3, 4, 5, 6 } };
+            // 1x2 from 1D array with larger stride gap
+            yield return new object[] { new int[] { 42, 99, 99, 99, 7, 99, 99, 99 }, new nint[] { 2 }, new nint[] { 4 }, new int[] { 42, 7 } };
+        }
+
+        [Theory]
+        [MemberData(nameof(NonDenseTensorData))]
+        public static void TensorSequenceEqualNonDenseTests(int[] data, nint[] shape, nint[] strides, int[] expectedLogical)
+        {
+            var ts1 = new ReadOnlyTensorSpan<int>(data, shape, strides);
             Assert.False(ts1.IsDense);
+
+            // Non-dense vs non-dense with same logical elements but different gap values
+            int[] data2 = (int[])data.Clone();
+            for (int i = 0; i < data2.Length; i++)
+            {
+                if (data2[i] == 99)
+                {
+                    data2[i] = 77;
+                }
+            }
+            var ts2 = new ReadOnlyTensorSpan<int>(data2, shape, strides);
             Assert.False(ts2.IsDense);
             Assert.True(ts1.SequenceEqual(ts2));
 
-            int[] d3 = [10, 20, 99, 99, 30, 41, 99, 99];
-            var ts3 = new ReadOnlyTensorSpan<int>(d3, [2, 2], [4, 1]);
-            Assert.False(ts1.SequenceEqual(ts3));
+            // Non-dense vs dense with same logical elements
+            var tsDense = new ReadOnlyTensorSpan<int>(expectedLogical, shape);
+            Assert.True(tsDense.IsDense);
+            Assert.True(ts1.SequenceEqual(tsDense));
+            Assert.True(tsDense.SequenceEqual(ts1));
 
-            int[] d4 = [10, 20, 30, 40];
-            var ts4 = new ReadOnlyTensorSpan<int>(d4, [2, 2], [2, 1]);
-            Assert.True(ts4.IsDense);
-            Assert.True(ts1.SequenceEqual(ts4));
-            Assert.True(ts4.SequenceEqual(ts1));
+            // TensorSpan overload also works
+            var tspan1 = new TensorSpan<int>(data, shape, strides);
+            Assert.True(tspan1.SequenceEqual(ts2));
 
-            var tspan1 = new TensorSpan<int>(d1, [2, 2], [4, 1]);
-            var tspan2 = new ReadOnlyTensorSpan<int>(d2, [2, 2], [4, 1]);
-            Assert.True(tspan1.SequenceEqual(tspan2));
+            // Differing logical element should return false
+            int[] data3 = (int[])data.Clone();
+            data3[0] = data3[0] + 1;
+            var ts3 = new ReadOnlyTensorSpan<int>(data3, shape, strides);
+            Assert.False(ts1.SequenceEqual(ts3));
         }
 
-        [Fact]
-        public static void TensorFillGaussianNormalDistributionNonDenseTests()
+        [Theory]
+        [MemberData(nameof(NonDenseTensorData))]
+        public static void TensorFillGaussianNormalDistributionNonDenseTests(int[] data, nint[] shape, nint[] strides, int[] expectedLogical)
         {
-            double[] data = new double[8];
-            var ts = new TensorSpan<double>(data, [2, 2], [4, 1]);
+            _ = expectedLogical;
+            double[] dblData = new double[data.Length];
+            var ts = new TensorSpan<double>(dblData, shape, strides);
             Assert.False(ts.IsDense);
 
             Tensor.FillGaussianNormalDistribution(ts, new Random(42));
 
+            // All logical elements should be filled
             foreach (double val in ts)
             {
                 Assert.NotEqual(0.0, val);
             }
 
-            Assert.Equal(0.0, data[2]);
-            Assert.Equal(0.0, data[3]);
-            Assert.Equal(0.0, data[6]);
-            Assert.Equal(0.0, data[7]);
+            // Gap positions should remain untouched (zero)
+            var denseSpan = new TensorSpan<double>(dblData, shape, strides);
+            var enumerator = denseSpan.GetEnumerator();
+            HashSet<int> logicalOffsets = new HashSet<int>();
+            nint[] indexes = new nint[shape.Length];
+            for (nint i = 0; i < ts.FlattenedLength; i++)
+            {
+                nint offset = 0;
+                // Compute i-th logical element's linear offset
+                nint remaining = i;
+                for (int d = shape.Length - 1; d >= 0; d--)
+                {
+                    nint dimIndex = remaining % shape[d];
+                    remaining /= shape[d];
+                    offset += dimIndex * strides[d];
+                }
+                logicalOffsets.Add((int)offset);
+            }
+
+            for (int i = 0; i < dblData.Length; i++)
+            {
+                if (!logicalOffsets.Contains(i))
+                {
+                    Assert.Equal(0.0, dblData[i]);
+                }
+            }
         }
 
-        [Fact]
-        public static void TensorFillUniformDistributionNonDenseTests()
+        [Theory]
+        [MemberData(nameof(NonDenseTensorData))]
+        public static void TensorFillUniformDistributionNonDenseTests(int[] data, nint[] shape, nint[] strides, int[] expectedLogical)
         {
-            double[] data = new double[8];
-            var ts = new TensorSpan<double>(data, [2, 2], [4, 1]);
+            _ = expectedLogical;
+            double[] dblData = new double[data.Length];
+            var ts = new TensorSpan<double>(dblData, shape, strides);
             Assert.False(ts.IsDense);
 
             Tensor.FillUniformDistribution(ts, new Random(42));
 
+            // All logical elements should be filled with values in [0, 1)
             foreach (double val in ts)
             {
                 Assert.InRange(val, 0.0, 1.0);
                 Assert.NotEqual(0.0, val);
             }
 
-            Assert.Equal(0.0, data[2]);
-            Assert.Equal(0.0, data[3]);
-            Assert.Equal(0.0, data[6]);
-            Assert.Equal(0.0, data[7]);
+            // Gap positions should remain untouched (zero)
+            HashSet<int> logicalOffsets = new HashSet<int>();
+            for (nint i = 0; i < ts.FlattenedLength; i++)
+            {
+                nint offset = 0;
+                nint remaining = i;
+                for (int d = shape.Length - 1; d >= 0; d--)
+                {
+                    nint dimIndex = remaining % shape[d];
+                    remaining /= shape[d];
+                    offset += dimIndex * strides[d];
+                }
+                logicalOffsets.Add((int)offset);
+            }
+
+            for (int i = 0; i < dblData.Length; i++)
+            {
+                if (!logicalOffsets.Contains(i))
+                {
+                    Assert.Equal(0.0, dblData[i]);
+                }
+            }
         }
 
-        [Fact]
-        public static void TensorIndexOfMaxNonDenseTests()
+        [Theory]
+        [MemberData(nameof(NonDenseTensorData))]
+        public static void TensorIndexOfMaxNonDenseTests(int[] data, nint[] shape, nint[] strides, int[] expectedLogical)
         {
-            int[] data = [1, 50, 99, 99, 3, 2, 99, 99];
-            var ts = new ReadOnlyTensorSpan<int>(data, [2, 2], [4, 1]);
+            _ = expectedLogical;
+            // Set a known max in the data at logical position
+            int[] testData = (int[])data.Clone();
+            // First, set all logical elements to small values
+            nint flatLen = 1;
+            foreach (nint s in shape)
+            {
+                flatLen *= s;
+            }
+
+            // Place the maximum value at the last logical position
+            nint lastOffset = 0;
+            nint rem = flatLen - 1;
+            for (int d = shape.Length - 1; d >= 0; d--)
+            {
+                nint dimIndex = rem % shape[d];
+                rem /= shape[d];
+                lastOffset += dimIndex * strides[d];
+            }
+            testData[(int)lastOffset] = 9999;
+
+            var ts = new ReadOnlyTensorSpan<int>(testData, shape, strides);
             Assert.False(ts.IsDense);
 
             nint idx = Tensor.IndexOfMax(ts);
-            Assert.Equal(1, idx);
+            Assert.Equal(flatLen - 1, idx);
         }
 
-        [Fact]
-        public static void TensorIndexOfMinNonDenseTests()
+        [Theory]
+        [MemberData(nameof(NonDenseTensorData))]
+        public static void TensorIndexOfMinNonDenseTests(int[] data, nint[] shape, nint[] strides, int[] expectedLogical)
         {
-            int[] data = [5, 50, 99, 99, 1, 2, 99, 99];
-            var ts = new ReadOnlyTensorSpan<int>(data, [2, 2], [4, 1]);
+            _ = expectedLogical;
+            // Set all logical elements to positive values, then put the minimum at the last logical position
+            int[] testData = new int[data.Length];
+            Array.Fill(testData, 50);
+
+            nint flatLen = 1;
+            foreach (nint s in shape)
+            {
+                flatLen *= s;
+            }
+
+            // Set all logical positions to values > 0
+            for (nint i = 0; i < flatLen; i++)
+            {
+                nint offset = 0;
+                nint remaining = i;
+                for (int d = shape.Length - 1; d >= 0; d--)
+                {
+                    nint dimIndex = remaining % shape[d];
+                    remaining /= shape[d];
+                    offset += dimIndex * strides[d];
+                }
+                testData[(int)offset] = (int)(i + 10);
+            }
+
+            // Place the minimum at the last logical position
+            nint lastOffset = 0;
+            nint rem = flatLen - 1;
+            for (int d = shape.Length - 1; d >= 0; d--)
+            {
+                nint dimIndex = rem % shape[d];
+                rem /= shape[d];
+                lastOffset += dimIndex * strides[d];
+            }
+            testData[(int)lastOffset] = -1;
+
+            var ts = new ReadOnlyTensorSpan<int>(testData, shape, strides);
             Assert.False(ts.IsDense);
 
             nint idx = Tensor.IndexOfMin(ts);
-            Assert.Equal(2, idx);
+            Assert.Equal(flatLen - 1, idx);
         }
 
-        [Fact]
-        public static void TensorIndexOfMaxMagnitudeNonDenseTests()
+        [Theory]
+        [MemberData(nameof(NonDenseTensorData))]
+        public static void TensorIndexOfMaxMagnitudeNonDenseTests(int[] data, nint[] shape, nint[] strides, int[] expectedLogical)
         {
-            int[] data = [1, -50, 99, 99, 3, 2, 99, 99];
-            var ts = new ReadOnlyTensorSpan<int>(data, [2, 2], [4, 1]);
+            _ = expectedLogical;
+            int[] testData = new int[data.Length];
+            Array.Fill(testData, 1);
+
+            nint flatLen = 1;
+            foreach (nint s in shape)
+            {
+                flatLen *= s;
+            }
+
+            // Set all logical positions to small values
+            for (nint i = 0; i < flatLen; i++)
+            {
+                nint offset = 0;
+                nint remaining = i;
+                for (int d = shape.Length - 1; d >= 0; d--)
+                {
+                    nint dimIndex = remaining % shape[d];
+                    remaining /= shape[d];
+                    offset += dimIndex * strides[d];
+                }
+                testData[(int)offset] = (int)(i + 1);
+            }
+
+            // Place the max magnitude at the last logical position
+            nint lastOffset = 0;
+            nint rem = flatLen - 1;
+            for (int d = shape.Length - 1; d >= 0; d--)
+            {
+                nint dimIndex = rem % shape[d];
+                rem /= shape[d];
+                lastOffset += dimIndex * strides[d];
+            }
+            testData[(int)lastOffset] = -9999;
+
+            var ts = new ReadOnlyTensorSpan<int>(testData, shape, strides);
             Assert.False(ts.IsDense);
 
             nint idx = Tensor.IndexOfMaxMagnitude(ts);
-            Assert.Equal(1, idx);
+            Assert.Equal(flatLen - 1, idx);
         }
 
-        [Fact]
-        public static void TensorIndexOfMinMagnitudeNonDenseTests()
+        [Theory]
+        [MemberData(nameof(NonDenseTensorData))]
+        public static void TensorIndexOfMinMagnitudeNonDenseTests(int[] data, nint[] shape, nint[] strides, int[] expectedLogical)
         {
-            int[] data = [5, 50, 99, 99, 1, -2, 99, 99];
-            var ts = new ReadOnlyTensorSpan<int>(data, [2, 2], [4, 1]);
+            _ = expectedLogical;
+            int[] testData = new int[data.Length];
+            Array.Fill(testData, 100);
+
+            nint flatLen = 1;
+            foreach (nint s in shape)
+            {
+                flatLen *= s;
+            }
+
+            // Set all logical positions to large magnitude values
+            for (nint i = 0; i < flatLen; i++)
+            {
+                nint offset = 0;
+                nint remaining = i;
+                for (int d = shape.Length - 1; d >= 0; d--)
+                {
+                    nint dimIndex = remaining % shape[d];
+                    remaining /= shape[d];
+                    offset += dimIndex * strides[d];
+                }
+                testData[(int)offset] = (int)(i + 100);
+            }
+
+            // Place the min magnitude at the first logical position
+            testData[0] = 0;
+
+            var ts = new ReadOnlyTensorSpan<int>(testData, shape, strides);
             Assert.False(ts.IsDense);
 
             nint idx = Tensor.IndexOfMinMagnitude(ts);
-            Assert.Equal(2, idx);
+            Assert.Equal(0, idx);
         }
 
-        [Fact]
-        public static void TensorResizeToNonDenseSourceTests()
+        [Theory]
+        [MemberData(nameof(NonDenseTensorData))]
+        public static void TensorResizeToNonDenseSourceTests(int[] data, nint[] shape, nint[] strides, int[] expectedLogical)
         {
-            int[] srcData = [10, 20, 99, 99, 30, 40, 99, 99];
-            var src = new ReadOnlyTensorSpan<int>(srcData, [2, 2], [4, 1]);
+            var src = new ReadOnlyTensorSpan<int>(data, shape, strides);
             Assert.False(src.IsDense);
 
-            int[] dstData = new int[6];
-            var dst = new TensorSpan<int>(dstData, [6], [1]);
+            // Resize to a larger dense destination
+            nint srcFlatLen = src.FlattenedLength;
+            int[] dstData = new int[(int)srcFlatLen + 2];
+            var dst = new TensorSpan<int>(dstData, [(nint)dstData.Length], [1]);
             Assert.True(dst.IsDense);
 
             Tensor.ResizeTo(src, dst);
 
-            Assert.Equal(10, dstData[0]);
-            Assert.Equal(20, dstData[1]);
-            Assert.Equal(30, dstData[2]);
-            Assert.Equal(40, dstData[3]);
-            Assert.Equal(0, dstData[4]);
-            Assert.Equal(0, dstData[5]);
+            for (int i = 0; i < expectedLogical.Length; i++)
+            {
+                Assert.Equal(expectedLogical[i], dstData[i]);
+            }
+            // Extra positions should be zero-filled
+            for (int i = expectedLogical.Length; i < dstData.Length; i++)
+            {
+                Assert.Equal(0, dstData[i]);
+            }
         }
 
-        [Fact]
-        public static void TensorResizeToNonDenseDestinationTests()
+        [Theory]
+        [MemberData(nameof(NonDenseTensorData))]
+        public static void TensorResizeToNonDenseDestinationTests(int[] data, nint[] shape, nint[] strides, int[] expectedLogical)
         {
-            int[] srcData = [10, 20, 30, 40, 50, 60];
-            var src = new ReadOnlyTensorSpan<int>(srcData, [6], [1]);
+            // Create a dense source with known values
+            var src = new ReadOnlyTensorSpan<int>(expectedLogical, [(nint)expectedLogical.Length], [1]);
             Assert.True(src.IsDense);
 
-            int[] dstData = new int[8];
-            var dst = new TensorSpan<int>(dstData, [2, 2], [4, 1]);
+            // Create a non-dense destination
+            int[] dstData = new int[data.Length];
+            var dst = new TensorSpan<int>(dstData, shape, strides);
             Assert.False(dst.IsDense);
 
+            nint copyLength = Math.Min(src.FlattenedLength, dst.FlattenedLength);
             Tensor.ResizeTo(src, dst);
 
-            Assert.Equal(10, dstData[0]);
-            Assert.Equal(20, dstData[1]);
-            Assert.Equal(0, dstData[2]);
-            Assert.Equal(0, dstData[3]);
-            Assert.Equal(30, dstData[4]);
-            Assert.Equal(40, dstData[5]);
-            Assert.Equal(0, dstData[6]);
-            Assert.Equal(0, dstData[7]);
+            // Verify logical elements were written correctly
+            int logicalIdx = 0;
+            foreach (int val in dst)
+            {
+                if (logicalIdx < expectedLogical.Length)
+                {
+                    Assert.Equal(expectedLogical[logicalIdx], val);
+                }
+                logicalIdx++;
+            }
         }
 
         [Fact]
         public static void TensorResizeNonDenseTests()
         {
+            // 2x3 tensor, slice to 2x2 (non-dense), then resize
             Tensor<int> tensor = Tensor.Create([10, 20, 30, 40, 50, 60], [2, 3]);
             Tensor<int> sliced = tensor.Slice(0..2, 0..2);
             Assert.False(sliced.IsDense);
@@ -883,6 +1084,20 @@ public static void TensorResizeNonDenseTests()
             Assert.Equal(10, resized[0]);
             Assert.Equal(20, resized[1]);
             Assert.Equal(40, resized[2]);
+
+            // 3x4 tensor, slice to 2x2 (non-dense), then resize larger
+            Tensor<int> tensor2 = Tensor.Create(Enumerable.Range(1, 12).ToArray(), [3, 4]);
+            Tensor<int> sliced2 = tensor2.Slice(0..2, 0..2);
+            Assert.False(sliced2.IsDense);
+
+            Tensor<int> resized2 = Tensor.Resize(sliced2, [6]);
+            Assert.Equal(6, resized2.FlattenedLength);
+            Assert.Equal(1, resized2[0]);
+            Assert.Equal(2, resized2[1]);
+            Assert.Equal(5, resized2[2]);
+            Assert.Equal(6, resized2[3]);
+            Assert.Equal(0, resized2[4]);
+            Assert.Equal(0, resized2[5]);
         }
 
         [Fact]

From 9fe536526d529ae9565ae58b0dc9352c2517b438 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 28 Feb 2026 11:04:46 +0000
Subject: [PATCH 5/6] Changes before error encountered

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
---
 .../System/Numerics/Tensors/netcore/Tensor.cs | 96 ++++++++++++++++---
 .../tests/TensorTests.cs                      | 55 +++++------
 2 files changed, 104 insertions(+), 47 deletions(-)

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 c5049cb8b93a19..cb2854ca7a2842 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
@@ -199,15 +199,21 @@ public static ref readonly TensorSpan<T> Concatenate<T>(scoped ReadOnlySpan<Tens
         public static ref readonly TensorSpan<T> ConcatenateOnDimension<T>(int dimension, scoped ReadOnlySpan<Tensor<T>> tensors, in TensorSpan<T> destination)
         {
             if (tensors.Length < 2)
+            {
                 ThrowHelper.ThrowArgument_ConcatenateTooFewTensors();
+            }
 
             if (dimension < -1 || dimension > tensors[0].Rank)
+            {
                 ThrowHelper.ThrowArgument_InvalidDimension();
+            }
 
             // Calculate total space needed.
             nint totalLength = 0;
             for (int i = 0; i < tensors.Length; i++)
+            {
                 totalLength += tensors[i].FlattenedLength;
+            }
 
             // If axis != -1, make sure all dimensions except the one to concatenate on match.
             if (dimension != -1)
@@ -217,13 +223,17 @@ public static ref readonly TensorSpan<T> ConcatenateOnDimension<T>(int dimension
                 for (int i = 1; i < tensors.Length; i++)
                 {
                     if (rank != tensors[i].Rank)
+                    {
                         ThrowHelper.ThrowArgument_InvalidConcatenateShape();
+                    }
                     for (int j = 0; j < rank; j++)
                     {
                         if (j != dimension)
                         {
                             if (tensors[0].Lengths[j] != tensors[i].Lengths[j])
+                            {
                                 ThrowHelper.ThrowArgument_InvalidConcatenateShape();
+                            }
                         }
                     }
                     sumOfAxis += tensors[i].Lengths[dimension];
@@ -235,10 +245,39 @@ public static ref readonly TensorSpan<T> ConcatenateOnDimension<T>(int dimension
                 lengths[dimension] = sumOfAxis;
 
                 if (!TensorShape.AreLengthsTheSame(destination.Lengths, lengths))
+                {
                     ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
+                }
             }
-            Span<T> dstSpan = MemoryMarshal.CreateSpan(ref destination._reference, (int)totalLength);
 
+            if (!destination.IsDense)
+            {
+                // For non-dense destinations, concatenate into a temporary dense buffer,
+                // then copy element-by-element to respect the destination's stride layout.
+                T[] tempBuffer = ArrayPool<T>.Shared.Rent((int)totalLength);
+                try
+                {
+                    Span<T> tempSpan = tempBuffer.AsSpan(0, (int)totalLength);
+                    ConcatenateOnDimensionToSpan(dimension, tensors, destination, tempSpan);
+                    ReadOnlyTensorSpan<T> tempTensor = new ReadOnlyTensorSpan<T>(tempBuffer, 0, destination.Lengths, []);
+                    TensorOperation.Invoke<TensorOperation.CopyTo<T>, T, T>(tempTensor, destination);
+                }
+                finally
+                {
+                    ArrayPool<T>.Shared.Return(tempBuffer);
+                }
+            }
+            else
+            {
+                Span<T> dstSpan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength);
+                ConcatenateOnDimensionToSpan(dimension, tensors, destination, dstSpan);
+            }
+
+            return ref destination;
+        }
+
+        private static void ConcatenateOnDimensionToSpan<T>(int dimension, scoped ReadOnlySpan<Tensor<T>> tensors, in TensorSpan<T> destination, Span<T> dstSpan)
+        {
             if (dimension is 0 or -1)
             {
                 for (int i = 0; i < tensors.Length; i++)
@@ -273,7 +312,6 @@ public static ref readonly TensorSpan<T> ConcatenateOnDimension<T>(int dimension
                 }
                 rentedBuffer.Dispose();
             }
-            return ref destination;
         }
 
         private static nint CalculateCopyLength(ReadOnlySpan<nint> lengths, int startingAxis)
@@ -1784,7 +1822,7 @@ public static bool SequenceEqual<T>(this scoped in ReadOnlyTensorSpan<T> tensor,
                 bool moved = enumerator2.MoveNext();
                 Debug.Assert(moved);
 
-                if (!EqualityComparer<T>.Default.Equals(enumerator1.Current, enumerator2.Current))
+                if (!(enumerator1.Current?.Equals(enumerator2.Current) ?? (object?)enumerator2.Current is null))
                 {
                     return false;
                 }
@@ -3631,9 +3669,16 @@ public static nint IndexOfMax<T>(scoped in ReadOnlyTensorSpan<T> x)
         private static nint IndexOfMaxFallback<T>(scoped in ReadOnlyTensorSpan<T> x)
             where T : INumber<T>
         {
-            T[] flat = new T[x.FlattenedLength];
-            x.FlattenTo(flat);
-            return TensorPrimitives.IndexOfMax<T>(flat);
+            T[] flat = ArrayPool<T>.Shared.Rent((int)x.FlattenedLength);
+            try
+            {
+                x.FlattenTo(flat);
+                return TensorPrimitives.IndexOfMax<T>(flat.AsSpan(0, (int)x.FlattenedLength));
+            }
+            finally
+            {
+                ArrayPool<T>.Shared.Return(flat);
+            }
         }
 
         #endregion
@@ -3656,9 +3701,16 @@ public static nint IndexOfMaxMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
         private static nint IndexOfMaxMagnitudeFallback<T>(scoped in ReadOnlyTensorSpan<T> x)
             where T : INumber<T>
         {
-            T[] flat = new T[x.FlattenedLength];
-            x.FlattenTo(flat);
-            return TensorPrimitives.IndexOfMaxMagnitude<T>(flat);
+            T[] flat = ArrayPool<T>.Shared.Rent((int)x.FlattenedLength);
+            try
+            {
+                x.FlattenTo(flat);
+                return TensorPrimitives.IndexOfMaxMagnitude<T>(flat.AsSpan(0, (int)x.FlattenedLength));
+            }
+            finally
+            {
+                ArrayPool<T>.Shared.Return(flat);
+            }
         }
         #endregion
 
@@ -3680,9 +3732,16 @@ public static nint IndexOfMin<T>(scoped in ReadOnlyTensorSpan<T> x)
         private static nint IndexOfMinFallback<T>(scoped in ReadOnlyTensorSpan<T> x)
             where T : INumber<T>
         {
-            T[] flat = new T[x.FlattenedLength];
-            x.FlattenTo(flat);
-            return TensorPrimitives.IndexOfMin<T>(flat);
+            T[] flat = ArrayPool<T>.Shared.Rent((int)x.FlattenedLength);
+            try
+            {
+                x.FlattenTo(flat);
+                return TensorPrimitives.IndexOfMin<T>(flat.AsSpan(0, (int)x.FlattenedLength));
+            }
+            finally
+            {
+                ArrayPool<T>.Shared.Return(flat);
+            }
         }
         #endregion
 
@@ -3706,9 +3765,16 @@ public static nint IndexOfMinMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
         private static nint IndexOfMinMagnitudeFallback<T>(scoped in ReadOnlyTensorSpan<T> x)
             where T : INumber<T>
         {
-            T[] flat = new T[x.FlattenedLength];
-            x.FlattenTo(flat);
-            return TensorPrimitives.IndexOfMinMagnitude<T>(flat);
+            T[] flat = ArrayPool<T>.Shared.Rent((int)x.FlattenedLength);
+            try
+            {
+                x.FlattenTo(flat);
+                return TensorPrimitives.IndexOfMinMagnitude<T>(flat.AsSpan(0, (int)x.FlattenedLength));
+            }
+            finally
+            {
+                ArrayPool<T>.Shared.Return(flat);
+            }
         }
         #endregion
 
diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
index 35d85ad38c0e61..993d0bef207542 100644
--- a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
+++ b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
@@ -767,6 +767,27 @@ public static void TensorSequenceEqualNonDenseTests(int[] data, nint[] shape, ni
             Assert.False(ts1.SequenceEqual(ts3));
         }
 
+        /// <summary>
+        /// Computes the set of buffer offsets that correspond to logical elements in a non-dense tensor.
+        /// </summary>
+        private static HashSet<int> ComputeLogicalOffsets(nint[] shape, nint[] strides, nint flattenedLength)
+        {
+            HashSet<int> logicalOffsets = new HashSet<int>();
+            for (nint i = 0; i < flattenedLength; i++)
+            {
+                nint offset = 0;
+                nint remaining = i;
+                for (int d = shape.Length - 1; d >= 0; d--)
+                {
+                    nint dimIndex = remaining % shape[d];
+                    remaining /= shape[d];
+                    offset += dimIndex * strides[d];
+                }
+                logicalOffsets.Add((int)offset);
+            }
+            return logicalOffsets;
+        }
+
         [Theory]
         [MemberData(nameof(NonDenseTensorData))]
         public static void TensorFillGaussianNormalDistributionNonDenseTests(int[] data, nint[] shape, nint[] strides, int[] expectedLogical)
@@ -785,24 +806,7 @@ public static void TensorFillGaussianNormalDistributionNonDenseTests(int[] data,
             }
 
             // Gap positions should remain untouched (zero)
-            var denseSpan = new TensorSpan<double>(dblData, shape, strides);
-            var enumerator = denseSpan.GetEnumerator();
-            HashSet<int> logicalOffsets = new HashSet<int>();
-            nint[] indexes = new nint[shape.Length];
-            for (nint i = 0; i < ts.FlattenedLength; i++)
-            {
-                nint offset = 0;
-                // Compute i-th logical element's linear offset
-                nint remaining = i;
-                for (int d = shape.Length - 1; d >= 0; d--)
-                {
-                    nint dimIndex = remaining % shape[d];
-                    remaining /= shape[d];
-                    offset += dimIndex * strides[d];
-                }
-                logicalOffsets.Add((int)offset);
-            }
-
+            HashSet<int> logicalOffsets = ComputeLogicalOffsets(shape, strides, ts.FlattenedLength);
             for (int i = 0; i < dblData.Length; i++)
             {
                 if (!logicalOffsets.Contains(i))
@@ -831,20 +835,7 @@ public static void TensorFillUniformDistributionNonDenseTests(int[] data, nint[]
             }
 
             // Gap positions should remain untouched (zero)
-            HashSet<int> logicalOffsets = new HashSet<int>();
-            for (nint i = 0; i < ts.FlattenedLength; i++)
-            {
-                nint offset = 0;
-                nint remaining = i;
-                for (int d = shape.Length - 1; d >= 0; d--)
-                {
-                    nint dimIndex = remaining % shape[d];
-                    remaining /= shape[d];
-                    offset += dimIndex * strides[d];
-                }
-                logicalOffsets.Add((int)offset);
-            }
-
+            HashSet<int> logicalOffsets = ComputeLogicalOffsets(shape, strides, ts.FlattenedLength);
             for (int i = 0; i < dblData.Length; i++)
             {
                 if (!logicalOffsets.Contains(i))

From ec7f3abf24ed3234f526b4a2ef9662f2aecf95b5 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 5 Mar 2026 21:41:07 +0000
Subject: [PATCH 6/6] Add regression test for concatenate with non-dense
 destination span

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
---
 .../tests/TensorTests.cs                      | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
index 993d0bef207542..aa90955b73c24b 100644
--- a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
+++ b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
@@ -1920,6 +1920,26 @@ public static void TensorConcatenateTests()
             }
         }
 
+        [Fact]
+        public static void TensorConcatenateNonDenseDestinationTests()
+        {
+            Tensor<int> backing = Tensor.CreateFromShape<int>([2, 3]);
+            TensorSpan<int> destination = backing.AsTensorSpan().Slice([0..2, 1..3]);
+            Assert.False(destination.IsDense);
+
+            Tensor<int> t0 = Tensor.Create([1, 2]);
+            Tensor<int> t1 = Tensor.Create([3, 4]);
+
+            Tensor.ConcatenateOnDimension(-1, [t0, t1], destination);
+
+            Assert.Equal(0, backing[0, 0]);
+            Assert.Equal(1, backing[0, 1]);
+            Assert.Equal(2, backing[0, 2]);
+            Assert.Equal(0, backing[1, 0]);
+            Assert.Equal(3, backing[1, 1]);
+            Assert.Equal(4, backing[1, 2]);
+        }
+
         [Fact]
         public static void TensorTransposeTests()
         {
