From 9f8b9bfdd26802e97daf4493f3c71aacee620be1 Mon Sep 17 00:00:00 2001 From: Michael Sharp <51342856+michaelgsharp@users.noreply.github.com> Date: Tue, 13 Aug 2024 02:36:28 -0600 Subject: [PATCH] Added all missing xml docs for Tensors (#106084) * Added all missing docs * Remove unnecessary 1591 and remove unnecessary props * updates from PR comments --------- Co-authored-by: Viktor Hofer --- .../src/Resources/Strings.resx | 6 +- .../src/System.Numerics.Tensors.csproj | 1 - .../src/System/NIndex.cs | 23 ++-- .../src/System/NRange.cs | 38 ++++-- .../Tensors/netcore/IReadOnlyTensor.cs | 114 +++++++++++++++++- .../Numerics/Tensors/netcore/ITensor.cs | 103 +++++++++++++++- .../Tensors/netcore/ReadOnlyTensorSpan.cs | 6 +- .../Tensors/netcore/Tensor.Factory.cs | 21 +++- .../System/Numerics/Tensors/netcore/Tensor.cs | 23 +++- .../Tensors/netcore/TensorExtensions.cs | 30 +++-- .../Numerics/Tensors/netcore/TensorSpan.cs | 6 +- .../src/System/ThrowHelper.cs | 4 +- 12 files changed, 318 insertions(+), 57 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx b/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx index 7fc5ad881af0c..4c22326d25be2 100644 --- a/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx +++ b/src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx @@ -198,8 +198,8 @@ When no ranges are specified the values tensor must be equal in size as the input tensor. - - Shapes are not broadcast compatible. + + Lengths are not broadcast compatible. The number of splits must perfectly divide the dimension. @@ -228,4 +228,4 @@ All tensors must have the same shape. - + \ 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 3221f6231ac3e..29c38e142ba80 100644 --- a/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj +++ b/src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj @@ -6,7 +6,6 @@ true Provides support for operating over tensors. ReferenceAssemblyExclusions.txt - true $(NoWarn);SYSLIB5001 diff --git a/src/libraries/System.Numerics.Tensors/src/System/NIndex.cs b/src/libraries/System.Numerics.Tensors/src/System/NIndex.cs index ab14d2ed80c92..bbd9bfbb81d6b 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/NIndex.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/NIndex.cs @@ -19,7 +19,7 @@ namespace System.Buffers { private readonly nint _value; - /// Construct an NIndex using a value and indicating if the NIndex is from the start or from the end. + /// Construct an using a value and indicating if the is from the start or from the end. /// The index value. it has to be zero or positive number. /// Indicating if the index is from the start or from the end. /// @@ -59,13 +59,13 @@ private NIndex(nint value) _value = value; } - /// Create an NIndex pointing at first element. + /// Create an pointing at first element. public static NIndex Start => new NIndex((nint)0); - /// Create an NIndex pointing at beyond last element. + /// Create an pointing at beyond last element. public static NIndex End => new NIndex((nint)~0); - /// Create an NIndex from the start at the position indicated by the value. + /// Create an from the start at the position indicated by the value. /// The index value from the start. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static NIndex FromStart(nint value) @@ -91,12 +91,19 @@ public static NIndex FromEnd(nint value) return new NIndex(~value); } -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 + /// + /// Converts the to an . + /// + /// The converted Index. public Index ToIndex() => checked((Index)this); + + /// + /// Converts the to an without doing bounds checks. + /// + /// The converted Index. public Index ToIndexUnchecked() => (Index)this; -#pragma warning restore 1591 - /// Returns the NIndex value. + /// Returns the value. public nint Value { get @@ -108,7 +115,7 @@ public nint Value } } - /// Indicates whether the NIndex is from the start or the end. + /// Indicates whether the is from the start or the end. public bool IsFromEnd => _value < 0; /// Calculate the offset from the start using the giving collection length. diff --git a/src/libraries/System.Numerics.Tensors/src/System/NRange.cs b/src/libraries/System.Numerics.Tensors/src/System/NRange.cs index 48211d5a4ee40..89036706a31f4 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/NRange.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/NRange.cs @@ -18,15 +18,15 @@ namespace System.Buffers [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public readonly struct NRange : IEquatable { - /// Represent the inclusive start NIndex of the NRange. + /// Represents the inclusive start NIndex of the NRange. public NIndex Start { get; } - /// Represent the exclusive end NIndex of the NRange. + /// Represents the exclusive end NIndex of the NRange. public NIndex End { get; } - /// Construct an NRange object using the start and end NIndexes. - /// Represent the inclusive start NIndex of the NRange. - /// Represent the exclusive end NIndex of the NRange. + /// Constructs an object using the start and end . + /// Represent the inclusive start of the . + /// Represent the exclusive end of the . public NRange(NIndex start, NIndex end) { Start = start; @@ -34,7 +34,7 @@ public NRange(NIndex start, NIndex end) } /// - /// Construct a object using a . + /// Constructs an object using a . /// /// The to use. public NRange(Range range) @@ -43,7 +43,7 @@ public NRange(Range range) End = range.End; } - /// Indicates whether the current NRange object is equal to another object of the same type. + /// Indicates whether the current object is equal to another object of the same type. /// An object to compare with this object public override bool Equals([NotNullWhen(true)] object? value) => value is NRange r && @@ -121,14 +121,34 @@ public override string ToString() private static void ThrowArgumentOutOfRangeException() => throw new ArgumentOutOfRangeException("length"); -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 + /// + /// Implicitly converts a to an . + /// + /// public static implicit operator NRange(Range range) => new NRange(range.Start, range.End); + /// + /// Explicitly converts an to a without doing bounds checks. + /// + /// to convert. public static explicit operator Range(NRange value) => new Range((Index)value.Start, (Index)value.End); + + /// + /// Explicitly converts an to a . + /// + /// to convert. public static explicit operator checked Range(NRange value) => new Range(checked((Index)value.Start), checked((Index)value.End)); + /// + /// Converts a to a . + /// + /// The converted Range. public Range ToRange() => new Range(checked((Index)Start), checked((Index)End)); + + /// + /// Converts a to a wihout doing bounds checks. + /// + /// The converted Range. public Range ToRangeUnchecked() => new Range((Index)Start, (Index)End); -#pragma warning restore 1591 } } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs index 16319b224c1db..9d42fa96d3f8a 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/IReadOnlyTensor.cs @@ -5,46 +5,152 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 - namespace System.Numerics.Tensors { + /// + /// Represents a read-only tensor. + /// + /// The type that implements this interface. + /// The element type. [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public interface IReadOnlyTensor : IEnumerable where TSelf : IReadOnlyTensor { + /// + /// Gets an empty tensor. + /// static abstract TSelf? Empty { get; } + /// + /// Gets a value that indicates whether the collection is currently empty. + /// bool IsEmpty { get; } + + /// + /// Gets a value that indicates whether the underlying buffer is pinned. + /// bool IsPinned { get; } + + /// + /// Gets the number of elements in the tensor. + /// nint FlattenedLength { get; } + + /// + /// Gets the number of dimensions in the tensor. + /// int Rank { get; } + /// + /// Gets the value at the specified indexes. + /// + /// The indexes to be used. T this[params scoped ReadOnlySpan indexes] { get; } + + /// + /// Gets the value at the specified indexes. + /// + /// The indexes to be used. T this[params scoped ReadOnlySpan indexes] { get; } + + /// + /// Gets the values at the specified ranges. + /// + /// The ranges to be used. TSelf this[params scoped ReadOnlySpan ranges] { get; } + /// + /// Creates a read-only tensor span for the entire underlying buffer. + /// + /// The converted . ReadOnlyTensorSpan AsReadOnlyTensorSpan(); + + /// + /// Creates a read-only tensor span for the specified start indexes. + /// + /// The start locations to be used. + /// The converted . ReadOnlyTensorSpan AsReadOnlyTensorSpan(params scoped ReadOnlySpan start); + + /// + /// Creates a read-only tensor span for the specified start indexes. + /// + /// The started indexes to be used. + /// The converted . ReadOnlyTensorSpan AsReadOnlyTensorSpan(params scoped ReadOnlySpan startIndex); + + /// + /// Creates a read-only tensor span for the specified ranges. + /// + /// The ranges to be used. + /// The converted . ReadOnlyTensorSpan AsReadOnlyTensorSpan(params scoped ReadOnlySpan range); + /// + /// Copies the tensor to the specified destination. The destination tensor must be equal to or larger than the source tensor. + /// + /// The destination span where the data should be copied to. void CopyTo(scoped TensorSpan destination); + + /// + /// Flattens the tensor to the specified destination. The destination span must be equal to or larger than the number of elements in the source tensor. + /// + /// The destination span where the data should be flattened to. void FlattenTo(scoped Span destination); + /// + /// Gets the length of each dimension in the tensor. + /// [UnscopedRef] ReadOnlySpan Lengths { get; } + /// + /// Gets the stride of each dimension in the tensor. + /// [UnscopedRef] ReadOnlySpan Strides { get; } + /// + /// Returns a reference to the 0th element of the tensor. If the tensor is empty, returns . + /// + /// + /// This method can be used for pinning and is required to support the use of the tensor within a fixed statement. + /// ref readonly T GetPinnableReference(); + + /// + /// Slices the tensor using the specified start indexes. + /// + /// The start locations to be used. + /// The sliced tensor. TSelf Slice(params scoped ReadOnlySpan start); + + /// + /// Slices the tensor using the specified start indexes. + /// + /// The start indexes to be used. + /// The sliced tensor. TSelf Slice(params scoped ReadOnlySpan startIndex); + + /// + /// Slices the tensor using the specified ranges. + /// + /// The ranges to be used. + /// The sliced tensor. TSelf Slice(params scoped ReadOnlySpan range); + + /// + /// Tries to copy the tensor to the specified destination. The destination tensor must be equal to or larger than the source tensor. + /// + /// The destination span where the data should be copied to. + /// if the copy succeeded, otherwise. bool TryCopyTo(scoped TensorSpan destination); + + /// + /// Tries to flatten the tensor to the specified destination. The destination span must be equal to or larger than the number of elements in the source tensor. + /// + /// The destination span where the data should be flattened to. + /// if the flatten succeeded, otherwise. bool TryFlattenTo(scoped Span destination); } } - -#pragma warning restore 1591 diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs index 3a6ee32d03d2a..eba3af96f69df 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ITensor.cs @@ -4,10 +4,13 @@ using System.Buffers; using System.Diagnostics.CodeAnalysis; -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 - namespace System.Numerics.Tensors { + /// + /// Represents a tensor. + /// + /// The type that implements this interface. + /// The element type. [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] public interface ITensor : IReadOnlyTensor @@ -17,27 +20,119 @@ public interface ITensor // It looks like C#/.NET currently hits limitations here as it believes TSelf and T could be the same type // Ideally we could annotate it such that they cannot be the same type and no conflicts would exist + /// + /// Creates a new tensor with the specified lengths. + /// + /// The lengths of each dimension. + /// to pin the underlying buffer. The default is . + /// + /// If is true the underlying buffer is created permanently pinned, otherwise the underlying buffer is not pinned. + /// The underlying buffer is initialized to default values. + /// static abstract TSelf Create(scoped ReadOnlySpan lengths, bool pinned = false); + + /// + /// Creates a new tensor with the specified lengths and strides. + /// + /// The lengths of each dimension. + /// The strides of each dimension. + /// to pin the underlying buffer. The default is . + /// + /// If is true the underlying buffer is created permanently pinned, otherwise the underlying buffer is not pinned. + /// The underlying buffer is initialized to default values. + /// static abstract TSelf Create(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false); + /// + /// Creates a new tensor with the specified lengths and strides. + /// + /// The lengths of each dimension. + /// to pin the underlying buffer. The default is . + /// + /// If is true the underlying buffer is created permanently pinned, otherwise the underlying buffer is not pinned. + /// The underlying buffer is not initialized. + /// static abstract TSelf CreateUninitialized(scoped ReadOnlySpan lengths, bool pinned = false); + + /// + /// Creates a new tensor with the specified lengths and strides. If is true the underlying buffer is + /// created permanently pinned, otherwise the underlying buffer is not pinned. The underlying buffer is not initialized. + /// + /// The lengths of each dimension. + /// The strides of each dimension. + /// to pin the underlying buffer. The default is . + /// + /// If is true the underlying buffer is created permanently pinned, otherwise the underlying buffer is not pinned. + /// The underlying buffer is not initialized. + /// static abstract TSelf CreateUninitialized(scoped ReadOnlySpan lengths, scoped ReadOnlySpan strides, bool pinned = false); + /// + /// Gets a value that idicates whether the collection is read-only. + /// bool IsReadOnly { get; } + /// + /// Gets the value at the specified indexes. + /// + /// The indexes to use. new T this[params scoped ReadOnlySpan indexes] { get; set; } + + /// + /// Gets the value at the specified indexes. + /// + /// The indexes to use. new T this[params scoped ReadOnlySpan indexes] { get; set; } + + /// + /// Gets the values at the specified ranges. + /// + /// The ranges to be used. new TSelf this[params scoped ReadOnlySpan ranges] { get; set; } + /// + /// Creates a tensor span for the entire underlying buffer. + /// + /// The converted . TensorSpan AsTensorSpan(); + + /// + /// Creates a tensor span for the specified start indexes. + /// + /// The start locations to be used. + /// The converted . TensorSpan AsTensorSpan(params scoped ReadOnlySpan start); + + /// + /// Creates a tensor span for the specified start indexes. + /// + /// The start indexes to be used. + /// The converted . TensorSpan AsTensorSpan(params scoped ReadOnlySpan startIndex); + + /// + /// Creates a tensor span for the specified ranges. + /// + /// The ranges to be used. + /// The converted . TensorSpan AsTensorSpan(params scoped ReadOnlySpan range); + /// + /// Clears the tensor. + /// void Clear(); + + /// + /// Fills the contents of this tensor with the given value. + /// void Fill(T value); + + /// + /// Returns a reference to the 0th element of the tensor. If the tensor is empty, returns . + /// + /// + /// This method can be used for pinning and is required to support the use of the tensor within a fixed statement. + /// new ref T GetPinnableReference(); } } - -#pragma warning restore 1591 diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan.cs index b3cfe8d808d6f..0e29b57c2fe54 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/ReadOnlyTensorSpan.cs @@ -599,10 +599,10 @@ public bool TryCopyTo(scoped TensorSpan destination) return retVal; } - //public static explicit operator TensorSpan(Array? array); -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 + /// + /// Defines an implicit conversion of an array to a . + /// public static implicit operator ReadOnlyTensorSpan(T[]? array) => new ReadOnlyTensorSpan(array); -#pragma warning restore 1591 /// /// Returns a with the name of the type and the number of elements. diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.Factory.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.Factory.cs index 373567e119c72..1e3904fb7504d 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.Factory.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/Tensor.Factory.cs @@ -12,6 +12,9 @@ namespace System.Numerics.Tensors { + /// + /// Provides methods for creating tensors. + /// public static partial class Tensor { /// @@ -175,7 +178,14 @@ public static Tensor CreateUninitialized(scoped ReadOnlySpan lengths return new Tensor(values, lengths, strides, pinned); } -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 + /// + /// Fills the given with random data in a Gaussian normal distribution. + /// can optionally be provided for seeding. + /// + /// The element type. + /// The destination where the data will be stored. + /// to provide random seeding. Defaults to if not provided. + /// public static ref readonly TensorSpan FillGaussianNormalDistribution(in TensorSpan destination, Random? random = null) where T : IFloatingPoint { Span span = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength); @@ -185,6 +195,14 @@ public static ref readonly TensorSpan FillGaussianNormalDistribution(in Te return ref destination; } + /// + /// Fills the given with random data in a uniform distribution. + /// can optionally be provided for seeding. + /// + /// The element type. + /// The destination where the data will be stored. + /// to provide random seeding. Defaults to if not provided. + /// public static ref readonly TensorSpan FillUniformDistribution(in TensorSpan destination, Random? random = null) where T : IFloatingPoint { Span span = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength); @@ -194,6 +212,5 @@ public static ref readonly TensorSpan FillUniformDistribution(in TensorSpa return ref destination; } -#pragma warning restore 1591 } } 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 76434215704c0..81c22de5fcffd 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 @@ -18,11 +18,12 @@ namespace System.Numerics.Tensors { + /// + /// Represents a tensor. + /// [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 public sealed class Tensor : ITensor, T> -#pragma warning restore 1591 { /// A byref or a native ptr. internal readonly T[] _values; @@ -367,13 +368,20 @@ public Tensor this[Tensor filter] } } -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 + /// + /// Defines an implicit conversion of an array to a . + /// public static implicit operator Tensor(T[] array) => new Tensor(array, [array.Length]); + /// + /// Defines an implicit conversion of a to a . + /// public static implicit operator TensorSpan(Tensor value) => new TensorSpan(ref MemoryMarshal.GetArrayDataReference(value._values), value._lengths, value._strides, value._flattenedLength); + /// + /// Defines an implicit conversion of a to a . + /// public static implicit operator ReadOnlyTensorSpan(Tensor value) => new ReadOnlyTensorSpan(ref MemoryMarshal.GetArrayDataReference(value._values), value._lengths, value._strides, value.FlattenedLength); -#pragma warning restore 1591 /// /// Converts this to a pointing to the same backing memory."/> @@ -618,12 +626,15 @@ public void Dispose() } // REVIEW: PENDING API REVIEW TO DETERMINE IMPLEMENTATION -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 + /// + /// Gets the hash code for the . + /// + /// The hash code of the tensor. + /// In all cases. public override int GetHashCode() { throw new NotImplementedException(); } -#pragma warning restore 1591 /// /// Get a string representation of the tensor. diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs index ac925475a2756..c01da7a52160d 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs @@ -18,10 +18,11 @@ namespace System.Numerics.Tensors { + /// + /// Provides methods for tensor operations. + /// [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)] -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 public static partial class Tensor -#pragma warning restore 1591 { #region AsReadOnlySpan /// @@ -98,7 +99,7 @@ public static void BroadcastTo(this Tensor source, in TensorSpan destin { nint[] newSize = Tensor.GetSmallestBroadcastableLengths(source.Lengths, destination.Lengths); if (!destination.Lengths.SequenceEqual(newSize)) - ThrowHelper.ThrowArgument_ShapesNotBroadcastCompatible(); + ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible(); ReadOnlyTensorSpan intermediate = LazyBroadcast(source, newSize); intermediate.FlattenTo(MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength)); @@ -113,7 +114,7 @@ public static void BroadcastTo(in this TensorSpan source, in TensorSpan { nint[] newSize = Tensor.GetSmallestBroadcastableLengths(source.Lengths, destination.Lengths); if (!destination.Lengths.SequenceEqual(newSize)) - ThrowHelper.ThrowArgument_ShapesNotBroadcastCompatible(); + ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible(); ReadOnlyTensorSpan intermediate = LazyBroadcast(source, newSize); intermediate.FlattenTo(MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength)); @@ -128,7 +129,7 @@ public static void BroadcastTo(in this ReadOnlyTensorSpan source, in Tenso { nint[] newSize = Tensor.GetSmallestBroadcastableLengths(source.Lengths, destination.Lengths); if (!destination.Lengths.SequenceEqual(newSize)) - ThrowHelper.ThrowArgument_ShapesNotBroadcastCompatible(); + ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible(); ReadOnlyTensorSpan intermediate = LazyBroadcast(source, newSize); intermediate.FlattenTo(MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength)); @@ -149,7 +150,7 @@ internal static TensorSpan LazyBroadcast(in TensorSpan input, ReadOnlyS return new TensorSpan(ref input._reference, shape, input.Strides, input._shape._memoryLength); if (!TensorHelpers.IsBroadcastableTo(input.Lengths, shape)) - ThrowHelper.ThrowArgument_ShapesNotBroadcastCompatible(); + ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible(); nint newSize = TensorSpanHelpers.CalculateTotalLength(shape); @@ -192,7 +193,7 @@ internal static ReadOnlyTensorSpan LazyBroadcast(in ReadOnlyTensorSpan return new TensorSpan(ref input._reference, shape, input.Strides, input._shape._memoryLength); if (!TensorHelpers.IsBroadcastableTo(input.Lengths, shape)) - ThrowHelper.ThrowArgument_ShapesNotBroadcastCompatible(); + ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible(); nint newSize = TensorSpanHelpers.CalculateTotalLength(shape); @@ -235,7 +236,7 @@ internal static Tensor LazyBroadcast(Tensor input, ReadOnlySpan l return new Tensor(input._values, lengths, false); if (!TensorHelpers.IsBroadcastableTo(input.Lengths, lengths)) - ThrowHelper.ThrowArgument_ShapesNotBroadcastCompatible(); + ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible(); nint newSize = TensorSpanHelpers.CalculateTotalLength(lengths); @@ -6589,11 +6590,17 @@ public static ref readonly TensorSpan Xor(scoped in ReadOnlyTensorSpan } #endregion -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 + /// + /// Gets the smallest broadcastable lengths for two shapes. + /// + /// The first shape to broadcast. + /// The second shape to broadcast. + /// The smallest lengths these shapes can be broadcast to. + /// The lengths of and are not broadcast compatible. public static nint[] GetSmallestBroadcastableLengths(ReadOnlySpan shape1, ReadOnlySpan shape2) { if (!TensorHelpers.IsBroadcastableTo(shape1, shape2)) - throw new Exception("Lengths are not broadcast compatible"); + ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible(); nint[] intermediateShape = TensorHelpers.GetIntermediateShape(shape1, shape2.Length); for (int i = 1; i <= shape1.Length; i++) @@ -6607,7 +6614,6 @@ public static nint[] GetSmallestBroadcastableLengths(ReadOnlySpan shape1, return intermediateShape; } -#pragma warning restore 1591 #region TensorPrimitivesHelpers private delegate void PerformCalculationSpanInSpanOut(ReadOnlySpan input, Span output); @@ -6740,7 +6746,7 @@ private static ref readonly TensorSpan TensorPrimitivesHelperTwoSpanInSpanOut ReadOnlyTensorSpan broadcastedLeft = Tensor.LazyBroadcast(left, newSize); ReadOnlyTensorSpan broadcastedRight = Tensor.LazyBroadcast(right, newSize); if (!destination.Lengths.SequenceEqual(newSize) || destination._shape._memoryLength < broadcastedLeft.FlattenedLength) - ThrowHelper.ThrowArgument_ShapesNotBroadcastCompatible(); + ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible(); nint rowLength = newSize[^1]; Span ospan; diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan.cs index 5c52cc68dc208..eacdc662c72d1 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorSpan.cs @@ -628,10 +628,10 @@ public bool TryCopyTo(scoped TensorSpan destination) return retVal; } - //public static explicit operator TensorSpan(Array? array); -#pragma warning disable 1591 // TODO: Document this API. https://github.com/dotnet/runtime/issues/105981 + /// + /// Defines an implicit conversion of an array to a . + /// public static implicit operator TensorSpan(T[]? array) => new TensorSpan(array); -#pragma warning restore 1591 /// /// Defines an implicit conversion of a to a diff --git a/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs b/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs index 4ccdb305b596c..6fc32bae55542 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/ThrowHelper.cs @@ -98,9 +98,9 @@ public static void ThrowArgument_SetSliceInvalidShapes(string? paramNames) } [DoesNotReturn] - public static void ThrowArgument_ShapesNotBroadcastCompatible() + public static void ThrowArgument_LengthsNotBroadcastCompatible() { - throw new ArgumentException(SR.ThrowArgument_ShapesNotBroadcastCompatible); + throw new ArgumentException(SR.ThrowArgument_LengthsNotBroadcastCompatible); } [DoesNotReturn]