Skip to content

Commit d757c03

Browse files
Add some additional Tensor APIs (#117739)
* Remove unnecessary usings from Tensor code * Add the TensorMarshal class * Fix the naming of various tensor create APIs to remove ambiguities * Add support for directly getting a contiguous span from a tensor * Update the compatibility supressions file for S.N.Tensors * Add tests for the new APIs * Fix some tests * Ensure the test calls TryGetSpan
1 parent 3fb6fbb commit d757c03

File tree

59 files changed

+1558
-537
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1558
-537
lines changed

src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.net9.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,18 @@ void System.IDisposable.Dispose() { }
4949
System.Numerics.Tensors.ReadOnlyTensorSpan<T> System.Numerics.Tensors.IReadOnlyTensor<System.Numerics.Tensors.TensorSpan<T>, T>.AsReadOnlyTensorSpan(params scoped System.ReadOnlySpan<System.Buffers.NRange> ranges) { throw null; }
5050
System.Numerics.Tensors.ReadOnlyTensorDimensionSpan<T> System.Numerics.Tensors.IReadOnlyTensor<System.Numerics.Tensors.TensorSpan<T>, T>.GetDimensionSpan(int dimension) { throw null; }
5151
ref readonly T System.Numerics.Tensors.IReadOnlyTensor<System.Numerics.Tensors.TensorSpan<T>, T>.GetPinnableReference() { throw null; }
52+
System.ReadOnlySpan<T> System.Numerics.Tensors.IReadOnlyTensor<System.Numerics.Tensors.TensorSpan<T>, T>.GetSpan(scoped System.ReadOnlySpan<nint> startIndexes, int length) { throw null; }
53+
System.ReadOnlySpan<T> System.Numerics.Tensors.IReadOnlyTensor<System.Numerics.Tensors.TensorSpan<T>, T>.GetSpan(scoped System.ReadOnlySpan<System.Buffers.NIndex> startIndexes, int length) { throw null; }
5254
System.Numerics.Tensors.TensorSpan<T> System.Numerics.Tensors.IReadOnlyTensor<System.Numerics.Tensors.TensorSpan<T>, T>.ToDenseTensor() { throw null; }
5355

5456
bool System.Numerics.Tensors.ITensor.IsReadOnly { get { throw null; } }
5557
object? System.Numerics.Tensors.ITensor.this[params scoped System.ReadOnlySpan<System.Buffers.NIndex> indexes] { get { throw null; } set { } }
5658
object? System.Numerics.Tensors.ITensor.this[params scoped System.ReadOnlySpan<nint> indexes] { get { throw null; } set { } }
5759
void System.Numerics.Tensors.ITensor.Fill(object value) { }
58-
static System.Numerics.Tensors.TensorSpan<T> ITensor<TensorSpan<T>, T>.Create(scoped System.ReadOnlySpan<nint> lengths, bool pinned) { throw null; }
59-
static System.Numerics.Tensors.TensorSpan<T> ITensor<TensorSpan<T>, T>.Create(scoped System.ReadOnlySpan<nint> lengths, scoped System.ReadOnlySpan<nint> strides, bool pinned) { throw null; }
60-
static System.Numerics.Tensors.TensorSpan<T> ITensor<TensorSpan<T>, T>.CreateUninitialized(scoped System.ReadOnlySpan<nint> lengths, bool pinned) { throw null; }
61-
static System.Numerics.Tensors.TensorSpan<T> ITensor<TensorSpan<T>, T>.CreateUninitialized(scoped System.ReadOnlySpan<nint> lengths, scoped System.ReadOnlySpan<nint> strides, bool pinned) { throw null; }
60+
static System.Numerics.Tensors.TensorSpan<T> ITensor<TensorSpan<T>, T>.CreateFromShape(scoped System.ReadOnlySpan<nint> lengths, bool pinned) { throw null; }
61+
static System.Numerics.Tensors.TensorSpan<T> ITensor<TensorSpan<T>, T>.CreateFromShape(scoped System.ReadOnlySpan<nint> lengths, scoped System.ReadOnlySpan<nint> strides, bool pinned) { throw null; }
62+
static System.Numerics.Tensors.TensorSpan<T> ITensor<TensorSpan<T>, T>.CreateFromShapeUninitialized(scoped System.ReadOnlySpan<nint> lengths, bool pinned) { throw null; }
63+
static System.Numerics.Tensors.TensorSpan<T> ITensor<TensorSpan<T>, T>.CreateFromShapeUninitialized(scoped System.ReadOnlySpan<nint> lengths, scoped System.ReadOnlySpan<nint> strides, bool pinned) { throw null; }
6264
System.Numerics.Tensors.TensorSpan<T> System.Numerics.Tensors.ITensor<System.Numerics.Tensors.TensorSpan<T>, T>.AsTensorSpan() { throw null; }
6365
System.Numerics.Tensors.TensorSpan<T> System.Numerics.Tensors.ITensor<System.Numerics.Tensors.TensorSpan<T>, T>.AsTensorSpan(params scoped System.ReadOnlySpan<nint> startIndexes) { throw null; }
6466
System.Numerics.Tensors.TensorSpan<T> System.Numerics.Tensors.ITensor<System.Numerics.Tensors.TensorSpan<T>, T>.AsTensorSpan(params scoped System.ReadOnlySpan<System.Buffers.NIndex> startIndexes) { throw null; }

src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs

Lines changed: 48 additions & 19 deletions
Large diffs are not rendered by default.

src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml

Lines changed: 365 additions & 1 deletion
Large diffs are not rendered by default.

src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@
171171
<Compile Include="System\Numerics\Tensors\netcore\TensorShape.cs" />
172172
<Compile Include="System\Numerics\Tensors\netcore\TensorSpan_1.cs" />
173173
<Compile Include="System\Numerics\Tensors\netcore\TensorSpanDebugView.cs" />
174+
<Compile Include="System\Runtime\InteropServices\TensorMarshal.cs" />
174175
</ItemGroup>
175176

176177
<ItemGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net9.0'))">

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Helpers.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System.Diagnostics.CodeAnalysis;
54
using System.Diagnostics;
65
using System.Runtime.CompilerServices;
76
using System.Runtime.InteropServices;

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.Single.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System.Runtime.CompilerServices;
5-
using System.Runtime.InteropServices;
6-
74
namespace System.Numerics.Tensors
85
{
96
/// <summary>Performs primitive tensor operations over spans of memory.</summary>

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Common/TensorPrimitives.IBooleanUnaryOperator.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Runtime.CompilerServices;
66
using System.Runtime.InteropServices;
77
using System.Runtime.Intrinsics;
8-
using static System.Numerics.Tensors.TensorPrimitives;
98

109
namespace System.Numerics.Tensors
1110
{

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Common/TensorPrimitives.IUnaryInputBinaryOutput.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System.Diagnostics;
54
using System.Runtime.CompilerServices;
65
using System.Runtime.InteropServices;
76
using System.Runtime.Intrinsics;

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor_1.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,21 @@ public interface IReadOnlyTensor<TSelf, T> : IReadOnlyTensor
7272
/// <remarks>This method is intended to support .NET compilers and is not intended to be called by user code.</remarks>
7373
ref readonly T GetPinnableReference();
7474

75+
/// <summary>Return a span that starts at the specified index and contains the specified number of items.</summary>
76+
/// <param name="startIndexes">The index at which the span should start.</param>
77+
/// <param name="length">The length for the span to return.</param>
78+
/// <returns>A span that consists of <paramref name="length" /> elements from the current tensor starting at <paramref name="startIndexes" />.</returns>
79+
/// <exception cref="ArgumentOutOfRangeException">
80+
/// <para><paramref name="startIndexes" /> does not contain <see cref="IReadOnlyTensor.Rank" /> elements.</para>
81+
/// -or-
82+
/// <para><paramref name="length" /> is negative, greater than <see cref="IReadOnlyTensor.FlattenedLength" />, or would cause the span to contain elements that should be skipped due to <see cref="IReadOnlyTensor.Strides" />.</para>
83+
/// </exception>
84+
/// <exception cref="IndexOutOfRangeException"><paramref name="startIndexes" /> is not a valid index into the tensor.</exception>
85+
ReadOnlySpan<T> GetSpan(scoped ReadOnlySpan<nint> startIndexes, int length);
86+
87+
/// <inheritdoc cref="GetSpan(ReadOnlySpan{nint}, int)" />
88+
ReadOnlySpan<T> GetSpan(scoped ReadOnlySpan<NIndex> startIndexes, int length);
89+
7590
/// <summary>Forms a slice out of the current tensor that begins at a specified index.</summary>
7691
/// <param name="startIndexes">The indexes at which to begin the slice.</param>
7792
/// <returns>A tensor that consists of all elements of the current tensor from <paramref name="startIndexes" /> to the end of the tensor.</returns>
@@ -112,5 +127,17 @@ public interface IReadOnlyTensor<TSelf, T> : IReadOnlyTensor
112127
/// <para>If the <paramref name="destination" /> length is shorter than the source, no items are copied and the method returns <c>false</c>.</para>
113128
/// </remarks>
114129
bool TryFlattenTo(scoped Span<T> destination);
130+
131+
/// <summary>Tries to return a span that starts at the specified index and contains the specified number of items.</summary>
132+
/// <param name="startIndexes">The index at which the span should start.</param>
133+
/// <param name="length">The desired length of the span to retrieve.</param>
134+
/// <param name="span">On successful return, a span that consists of <paramref name="length" /> elements from the current tensor starting at <paramref name="startIndexes" />.</param>
135+
/// <returns><c>true</c> if a span was successfully retrieved; otherwise, <c>false</c> which indicates <paramref name="length" /> was invalid.</returns>
136+
/// <exception cref="ArgumentOutOfRangeException"><paramref name="startIndexes" /> does not contain <see cref="IReadOnlyTensor.Rank" /> elements.</exception>
137+
/// <exception cref="IndexOutOfRangeException"><paramref name="startIndexes" /> is not a valid index into the tensor.</exception>
138+
bool TryGetSpan(scoped ReadOnlySpan<nint> startIndexes, int length, out ReadOnlySpan<T> span);
139+
140+
/// <inheritdoc cref="TryGetSpan(ReadOnlySpan{nint}, int, out ReadOnlySpan{T})" />
141+
bool TryGetSpan(scoped ReadOnlySpan<NIndex> startIndexes, int length, out ReadOnlySpan<T> span);
115142
}
116143
}

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Buffers;
5-
using System.Diagnostics.CodeAnalysis;
65

76
namespace System.Numerics.Tensors
87
{

0 commit comments

Comments
 (0)