Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -225,4 +225,7 @@
<data name="Argument_IncompatibleDimensions" xml:space="preserve">
<value>Incompatible dimensions for provided tensors. left.Lengths[1] == {0} while right.Lengths[1] == {1}.</value>
</data>
</root>
<data name="ThrowArgument_StackShapesNotSame" xml:space="preserve">
<value>All tensors must have the same shape.</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
<Compile Include="System\Numerics\Tensors\netcore\ITensor.cs" />
<Compile Include="System\Numerics\Tensors\netcore\IReadOnlyTensor.cs" />
<Compile Include="System\Numerics\Tensors\netcore\TensorSpanDebugView.cs" />
<Compile Include="System\Numerics\Tensors\netcore\TensorSpanExtensions.cs" />
<Compile Include="System\Numerics\Tensors\netcore\ReadOnlyTensorSpan.cs" />
<Compile Include="System\Numerics\Tensors\netcore\TensorSpanHelpers.cs" />
<Compile Include="System\Numerics\Tensors\netcore\TensorSpanHelpers.T.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,14 @@ public void FlattenTo(scoped Span<T> destination)
nint copiedValues = 0;
while (copiedValues < _flattenedLength)
{
TensorSpanHelpers.Memmove(destination.Slice(checked((int)copiedValues)), ref Unsafe.Add(ref _reference, TensorSpanHelpers.ComputeLinearIndex(curIndexes, Strides, Lengths)), Lengths[Rank - 1]);
if (Strides[Rank - 1] == 0)
{
destination.Slice(checked((int)copiedValues), (int)Lengths[Rank - 1]).Fill(Unsafe.Add(ref _reference, TensorSpanHelpers.ComputeLinearIndex(curIndexes, Strides, Lengths)));
}
else
{
TensorSpanHelpers.Memmove(destination.Slice(checked((int)copiedValues)), ref Unsafe.Add(ref _reference, TensorSpanHelpers.ComputeLinearIndex(curIndexes, Strides, Lengths)), Lengths[Rank - 1]);
}
TensorSpanHelpers.AdjustIndexes(Rank - 2, 1, curIndexes, _lengths);
copiedValues += Lengths[Rank - 1];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.VisualBasic;

#pragma warning disable CS8601 // Possible null reference assignment.
Expand All @@ -19,7 +20,6 @@ public static partial class Tensor
/// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
/// <param name="pinned">A <see cref="bool"/> whether the underlying data should be pinned or not.</param>
public static Tensor<T> Create<T>(scoped ReadOnlySpan<nint> lengths, bool pinned = false)
where T : IEquatable<T>
{
nint linearLength = TensorSpanHelpers.CalculateTotalLength(lengths);
T[] values = pinned ? GC.AllocateArray<T>((int)linearLength, pinned) : (new T[linearLength]);
Expand All @@ -33,7 +33,6 @@ public static Tensor<T> Create<T>(scoped ReadOnlySpan<nint> lengths, bool pinned
/// <param name="strides">A <see cref="ReadOnlySpan{T}"/> indicating the strides of each dimension.</param>
/// <param name="pinned">A <see cref="bool"/> whether the underlying data should be pinned or not.</param>
public static Tensor<T> Create<T>(scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides, bool pinned = false)
where T : IEquatable<T>
{
nint linearLength = TensorSpanHelpers.CalculateTotalLength(lengths);
T[] values = pinned ? GC.AllocateArray<T>((int)linearLength, pinned) : (new T[linearLength]);
Expand All @@ -48,7 +47,7 @@ public static Tensor<T> Create<T>(scoped ReadOnlySpan<nint> lengths, scoped Read
/// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static Tensor<T> Create<T>(T[] values, scoped ReadOnlySpan<nint> lengths)
where T : IEquatable<T> => Create(values, lengths, []);
=> Create(values, lengths, []);

/// <summary>
/// Creates a <see cref="Tensor{T}"/> from the provided <paramref name="values"/>. If the product of the
Expand All @@ -60,51 +59,40 @@ public static Tensor<T> Create<T>(T[] values, scoped ReadOnlySpan<nint> lengths)
/// <param name="isPinned">A <see cref="bool"/> indicating whether the <paramref name="values"/> were pinned or not.</param>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static Tensor<T> Create<T>(T[] values, scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides, bool isPinned = false)
where T : IEquatable<T>
{
return new Tensor<T>(values, lengths, strides, isPinned);
}

/// <summary>
/// Creates a <see cref="Tensor{T}"/> and does not initialize it. If <paramref name="pinned"/> is true, the memory will be pinned.
/// </summary>
/// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
/// <param name="pinned">A <see cref="bool"/> whether the underlying data should be pinned or not.</param>
public static Tensor<T> CreateUninitialized<T>(scoped ReadOnlySpan<nint> lengths, bool pinned = false)
where T : IEquatable<T> => CreateUninitialized<T>(lengths, [], pinned);


/// <summary>
/// Creates a <see cref="Tensor{T}"/> and does not initialize it. If <paramref name="pinned"/> is true, the memory will be pinned.
/// Creates a <see cref="Tensor{T}"/> and initializes it with the data from <paramref name="data"/>.
/// </summary>
/// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
/// <param name="strides">A <see cref="ReadOnlySpan{T}"/> indicating the strides of each dimension.</param>
/// <param name="pinned">A <see cref="bool"/> whether the underlying data should be pinned or not.</param>
public static Tensor<T> CreateUninitialized<T>(scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides, bool pinned = false )
where T : IEquatable<T>
/// <param name="data">A <see cref="IEnumerable{T}"/> with the data to use for the initialization.</param>
/// <param name="lengths"></param>
public static Tensor<T> Create<T>(IEnumerable<T> data, scoped ReadOnlySpan<nint> lengths)
{
nint linearLength = TensorSpanHelpers.CalculateTotalLength(lengths);
T[] values = GC.AllocateUninitializedArray<T>((int)linearLength, pinned);
return new Tensor<T>(values, lengths, strides, pinned);
T[] values = data.ToArray();
return new Tensor<T>(values, lengths.IsEmpty ? [values.Length] : lengths, false);
}

/// <summary>
/// Creates a <see cref="Tensor{T}"/> and initializes it with the data from <paramref name="data"/>.
/// </summary>
/// <param name="data">A <see cref="IEnumerable{T}"/> with the data to use for the initialization.</param>
public static Tensor<T> CreateFromEnumerable<T>(IEnumerable<T> data)
where T : IEquatable<T>, IEqualityOperators<T, T, bool>
/// <param name="lengths"></param>
/// <param name="strides"></param>
/// <param name="isPinned"></param>
public static Tensor<T> Create<T>(IEnumerable<T> data, scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides, bool isPinned = false)
{
T[] values = data.ToArray();
return new Tensor<T>(values, [values.Length], false);
return new Tensor<T>(values, lengths.IsEmpty ? [values.Length] : lengths, strides, isPinned);
}

/// <summary>
/// Creates a <see cref="Tensor{T}"/> and initializes it with random data uniformly distributed.
/// </summary>
/// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
public static Tensor<T> CreateAndFillUniformDistribution<T>(params scoped ReadOnlySpan<nint> lengths)
where T : IEquatable<T>, IEqualityOperators<T, T, bool>, IFloatingPoint<T>
where T : IFloatingPoint<T>
{
nint linearLength = TensorSpanHelpers.CalculateTotalLength(lengths);
T[] values = new T[linearLength];
Expand All @@ -121,16 +109,16 @@ public static Tensor<T> CreateAndFillUniformDistribution<T>(params scoped ReadOn
/// </summary>
/// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
public static Tensor<T> CreateAndFillGaussianNormalDistribution<T>(params scoped ReadOnlySpan<nint> lengths)
where T : IEquatable<T>, IEqualityOperators<T, T, bool>, IFloatingPoint<T>
where T : IFloatingPoint<T>
{
nint linearLength = TensorSpanHelpers.CalculateTotalLength(lengths);
T[] values = new T[linearLength];
GaussianDistribution(ref values, linearLength);
GaussianDistribution<T>(values, linearLength);
return new Tensor<T>(values, lengths, false);
}

private static void GaussianDistribution<T>(ref T[] values, nint linearLength)
where T : IEquatable<T>, IEqualityOperators<T, T, bool>, IFloatingPoint<T>
private static void GaussianDistribution<T>(in Span<T> values, nint linearLength)
where T : IFloatingPoint<T>
{
Random rand = Random.Shared;
for (int i = 0; i < linearLength; i++)
Expand All @@ -141,5 +129,45 @@ private static void GaussianDistribution<T>(ref T[] values, nint linearLength)
}
}
#endregion

/// <summary>
/// Creates a <see cref="Tensor{T}"/> and does not initialize it. If <paramref name="pinned"/> is true, the memory will be pinned.
/// </summary>
/// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
/// <param name="pinned">A <see cref="bool"/> whether the underlying data should be pinned or not.</param>
public static Tensor<T> CreateUninitialized<T>(scoped ReadOnlySpan<nint> lengths, bool pinned = false)
=> CreateUninitialized<T>(lengths, [], pinned);

/// <summary>
/// Creates a <see cref="Tensor{T}"/> and does not initialize it. If <paramref name="pinned"/> is true, the memory will be pinned.
/// </summary>
/// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
/// <param name="strides">A <see cref="ReadOnlySpan{T}"/> indicating the strides of each dimension.</param>
/// <param name="pinned">A <see cref="bool"/> whether the underlying data should be pinned or not.</param>
public static Tensor<T> CreateUninitialized<T>(scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides, bool pinned = false)
{
nint linearLength = TensorSpanHelpers.CalculateTotalLength(lengths);
T[] values = GC.AllocateUninitializedArray<T>((int)linearLength, pinned);
return new Tensor<T>(values, lengths, strides, pinned);
}

public static ref readonly TensorSpan<T> FillGaussianNormalDistribution<T>(in TensorSpan<T> destination) where T : IFloatingPoint<T>
{
Span<T> span = MemoryMarshal.CreateSpan<T>(ref destination._reference, (int)destination._flattenedLength);

GaussianDistribution<T>(span, destination._flattenedLength);

return ref destination;
}

public static ref readonly TensorSpan<T> FillUniformDistribution<T>(in TensorSpan<T> destination) where T : IFloatingPoint<T>
{
Span<T> span = MemoryMarshal.CreateSpan<T>(ref destination._reference, (int)destination._flattenedLength);

for (int i = 0; i < span.Length; i++)
span[i] = T.CreateChecked(Random.Shared.NextDouble());

return ref destination;
}
}
}
Loading