Skip to content

Mark the new tensor APIs as experimental for .NET 9 #105268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace System.Buffers
{
[System.Diagnostics.CodeAnalysis.Experimental("SNTEXP0001")]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CC. @terrajobst, I don't think we have an existing format for these. So I've somewhat just followed what some other users (ASP.NET/Azure) are doing here.

Namely, SNT for System.Numerics.Tensors, then EXP for Experimental, then 0001 since this is the first ID.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wording we get from this resembles:

SNTEXP0001: 'System.Numerics.Tensors.IReadOnlyTensor<System.Numerics.Tensors.Tensor<T>, T>' is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

Copy link
Member

@jeffhandley jeffhandley Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@terrajobst Should we instead use SYSLIB5### to follow suit of Obsoletions (SYSLIB0###) and Analyzers (SYSLIB1###) and leave plenty of room for analyzers?

Copy link
Contributor

@terrajobst terrajobst Jul 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should stick to SYSLIB for all diagnostics (obsoletions, experimental, and analyzers).

My concern with having separate prefixes is that it will be very inconsistent across all the parties. It's hard enough to come up with a prefix that is short enough and identifies a single party that can keep track of the numbers to avoid duplicates. Asking folks to have separate prefixes for obsoletions, experimental, and general purposes analyzers and have that scheme make sense across all parties, is a bit too much IMHO. And frankly it doesn't seem to add much more value to the consumer as the way a given diagnostic needs to be addressed often differs between different cases within the same category anyway. So the expectation is: read the message and follow the link if you need more information.

I don't have strong opinions on whether we should use numeric ranges for the different categories; if having separate ranges makes our lives easier (or is more consistent with what we have done before), then let's do that. If not, I don't think it's worth introducing though.

public readonly partial struct NIndex : System.IEquatable<System.Buffers.NIndex>
{
private readonly int _dummyPrimitive;
Expand All @@ -29,6 +30,7 @@ namespace System.Buffers
public System.Index ToIndexUnchecked() { throw null; }
public override string ToString() { throw null; }
}
[System.Diagnostics.CodeAnalysis.Experimental("SNTEXP0001")]
public readonly partial struct NRange : System.IEquatable<System.Buffers.NRange>
{
private readonly int _dummyPrimitive;
Expand All @@ -53,6 +55,7 @@ namespace System.Buffers
}
namespace System.Numerics.Tensors
{
[System.Diagnostics.CodeAnalysis.Experimental("SNTEXP0001")]
public partial interface IReadOnlyTensor<TSelf, T> : System.Collections.Generic.IEnumerable<T>, System.Collections.IEnumerable where TSelf : System.Numerics.Tensors.IReadOnlyTensor<TSelf, T>
{
static abstract TSelf? Empty { get; }
Expand Down Expand Up @@ -80,6 +83,7 @@ public partial interface IReadOnlyTensor<TSelf, T> : System.Collections.Generic.
bool TryCopyTo(scoped System.Numerics.Tensors.TensorSpan<T> destination);
bool TryFlattenTo(scoped System.Span<T> destination);
}
[System.Diagnostics.CodeAnalysis.Experimental("SNTEXP0001")]
public partial interface ITensor<TSelf, T> : System.Collections.Generic.IEnumerable<T>, System.Collections.IEnumerable, System.Numerics.Tensors.IReadOnlyTensor<TSelf, T> where TSelf : System.Numerics.Tensors.ITensor<TSelf, T>
{
bool IsReadOnly { get; }
Expand All @@ -98,6 +102,7 @@ public partial interface ITensor<TSelf, T> : System.Collections.Generic.IEnumera
void Fill(T value);
new ref T GetPinnableReference();
}
[System.Diagnostics.CodeAnalysis.Experimental("SNTEXP0001")]
public readonly ref partial struct ReadOnlyTensorSpan<T>
{
private readonly object _dummy;
Expand Down Expand Up @@ -157,6 +162,7 @@ public ref partial struct Enumerator
public bool MoveNext() { throw null; }
}
}
[System.Diagnostics.CodeAnalysis.Experimental("SNTEXP0001")]
public static partial class Tensor
{
public static System.Numerics.Tensors.Tensor<T> Abs<T>(in System.Numerics.Tensors.ReadOnlyTensorSpan<T> x) where T : System.Numerics.INumberBase<T> { throw null; }
Expand Down Expand Up @@ -674,6 +680,7 @@ public static void Truncate<T>(System.ReadOnlySpan<T> x, System.Span<T> destinat
public static void Xor<T>(System.ReadOnlySpan<T> x, System.ReadOnlySpan<T> y, System.Span<T> destination) where T : System.Numerics.IBitwiseOperators<T, T, T> { }
public static void Xor<T>(System.ReadOnlySpan<T> x, T y, System.Span<T> destination) where T : System.Numerics.IBitwiseOperators<T, T, T> { }
}
[System.Diagnostics.CodeAnalysis.Experimental("SNTEXP0001")]
public readonly ref partial struct TensorSpan<T>
{
private readonly object _dummy;
Expand Down Expand Up @@ -735,6 +742,7 @@ public ref partial struct Enumerator
public bool MoveNext() { throw null; }
}
}
[System.Diagnostics.CodeAnalysis.Experimental("SNTEXP0001")]
public sealed partial class Tensor<T> : System.Collections.Generic.IEnumerable<T>, System.Collections.IEnumerable, System.Numerics.Tensors.IReadOnlyTensor<System.Numerics.Tensors.Tensor<T>, T>, System.Numerics.Tensors.ITensor<System.Numerics.Tensors.Tensor<T>, T>
{
internal Tensor() { }
Expand Down
1 change: 1 addition & 0 deletions src/libraries/System.Numerics.Tensors/src/System/NIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace System.Buffers
/// int lastElement = someArray[^1]; // lastElement = 5
/// </code>
/// </remarks>
[Experimental("SNTEXP0001")]
public readonly struct NIndex : IEquatable<NIndex>
{
private readonly nint _value;
Expand Down
1 change: 1 addition & 0 deletions src/libraries/System.Numerics.Tensors/src/System/NRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace System.Buffers
/// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 }
/// </code>
/// </remarks>
[Experimental("SNTEXP0001")]
public readonly struct NRange : IEquatable<NRange>
{
/// <summary>Represent the inclusive start NIndex of the NRange.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace System.Numerics.Tensors
{
[Experimental("SNTEXP0001")]
public interface IReadOnlyTensor<TSelf, T> : IEnumerable<T>
where TSelf : IReadOnlyTensor<TSelf, T>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers;
using System.Diagnostics.CodeAnalysis;

namespace System.Numerics.Tensors
{
[Experimental("SNTEXP0001")]
public interface ITensor<TSelf, T>
: IReadOnlyTensor<TSelf, T>
where TSelf : ITensor<TSelf, T>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace System.Numerics.Tensors
/// </summary>
[DebuggerTypeProxy(typeof(TensorSpanDebugView<>))]
[DebuggerDisplay("{ToString(),raw}")]
[Experimental("SNTEXP0001")]
public readonly ref struct ReadOnlyTensorSpan<T>
{
/// <summary>A byref or a native ptr.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.VisualBasic;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;
Expand All @@ -17,6 +18,7 @@

namespace System.Numerics.Tensors
{
[Experimental("SNTEXP0001")]
public sealed class Tensor<T>
: ITensor<Tensor<T>, T>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Security.Cryptography;
using System.Runtime.Serialization;
using System.Diagnostics.CodeAnalysis;

#pragma warning disable CS8601 // Possible null reference assignment.
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.

namespace System.Numerics.Tensors
{
[Experimental("SNTEXP0001")]
public static partial class Tensor
{
#region AsReadOnlySpan
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices;

namespace System.Numerics.Tensors
{
[Experimental("SNTEXP0001")]
internal static class TensorHelpers
{

Expand Down
Loading