Skip to content

Commit

Permalink
[release/8.0] Numerics and Tensors backport (#92245)
Browse files Browse the repository at this point in the history
* added Bcl.Numerics

* Adding a naive implementation of various primitive tensor operations (#91228)

* Adding a naive implementation of various primitive tensor operations

* Adding tests covering the new tensor primitives APIs

* Adding tensor primitives APIs to the ref assembly

* Allow .NET Framework to build/run

* Sync TFMs between ref and src, csproj simplication and clean-up

* Apply suggestions from code review

Co-authored-by: Viktor Hofer <viktor.hofer@microsoft.com>

* Don't use var

* Fix the S.N.Tensors readme and remove the file marking it as non-shipping

---------

Co-authored-by: Viktor Hofer <viktor.hofer@microsoft.com>
Co-authored-by: Michael Sharp <51342856+michaelgsharp@users.noreply.github.com>

* Start vectorizing TensorPrimitives (#91596)

* Start vectorizing TensorPrimitives

Just does two functions to establish the files into which the rest of the implementations can be moved.

* 6 more naive methods for Tensor Primitives. (#92142)

* 6 more naive methods

* updates from pr comments

* Add remaining set of TensorPrimitives APIs for .NET 8 (#92154)

* Add remaining set of TensorPrimitives APIs for .NET 8

Adds non-vectorized implementations of:
- Max
- Min
- MaxMagnitude
- MinMagnitude
- IndexOfMax
- IndexOfMin
- IndexOfMaxMagnitude
- ConvertToHalf (only on .NET Core)
- ConvertToSingle (only on .NET Core)
- IndexOfMinMagnitude

Adds vectorized implementations of:
- Sum
- SumOfSquares
- SumOfMagnitudes
- Product
- ProductOfSums
- ProductOfDifferences

Also includes the helpers that'll make it trivial to vectorize Dot.

Beyond vectorizing the non-vectorized ones, the vectorized implementations should be improved further, including:
- Handling alignment better
- Vectorizing the remainder that doesn't fit in a vector rather than falling back to scalar

* Cleanup after previous PR, vectorize CosineSimilarity/Dot/L2Normalize/Distance, add tests

* Address PR feedback, and fix a few other issues

* Fix TensorPrimitives.CosineSimilarity to use vectorized implementations (#92204)

* Fixed duplicated code from merge.

* New Microsoft.BCL.Numerics package (#91074)

* bcl numberics library added

* bcl done

* added explicit 2.1 target

* Minor doc updates

* Apply suggestions from code review

Co-authored-by: Viktor Hofer <viktor.hofer@microsoft.com>

* fixes from PR comments

* minor csproj fixes

* fixed ref target frameworks

* minor ref csproj updates

* minor csproj updates

---------

Co-authored-by: Viktor Hofer <viktor.hofer@microsoft.com>

* Microsoft.Bcl.Numerics.Tests: fix restore failure when DotNetBuildFromSource. (#91402)

* Microsoft.Bcl.Numerics.Tests: fix restore failure when DotNetBuildFromSource.

* Use NetCoreAppCurrent.

* Try fix CI test failures.

---------

Co-authored-by: Tanner Gooding <tagoo@outlook.com>
Co-authored-by: Viktor Hofer <viktor.hofer@microsoft.com>
Co-authored-by: Stephen Toub <stoub@microsoft.com>
Co-authored-by: Tom Deseyn <tom.deseyn@gmail.com>
  • Loading branch information
5 people committed Sep 19, 2023
1 parent e00e6aa commit 4b7c754
Show file tree
Hide file tree
Showing 46 changed files with 6,091 additions and 23,389 deletions.
8 changes: 4 additions & 4 deletions src/coreclr/jit/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2734,7 +2734,7 @@ float FloatingPointUtils::maximumNumber(float x, float y)
//
// It propagates NaN inputs back to the caller and
// otherwise returns the lesser of the inputs. It
// treats +0 as lesser than -0 as per the specification.
// treats +0 as greater than -0 as per the specification.
//
// Arguments:
// val1 - left operand
Expand Down Expand Up @@ -2763,7 +2763,7 @@ double FloatingPointUtils::minimum(double val1, double val2)
//
// It propagates NaN inputs back to the caller and
// otherwise returns the input with a lesser magnitude.
// It treats +0 as lesser than -0 as per the specification.
// It treats +0 as greater than -0 as per the specification.
//
// Arguments:
// x - left operand
Expand Down Expand Up @@ -2856,7 +2856,7 @@ double FloatingPointUtils::minimumNumber(double x, double y)
//
// It propagates NaN inputs back to the caller and
// otherwise returns the lesser of the inputs. It
// treats +0 as lesser than -0 as per the specification.
// treats +0 as greater than -0 as per the specification.
//
// Arguments:
// val1 - left operand
Expand Down Expand Up @@ -2885,7 +2885,7 @@ float FloatingPointUtils::minimum(float val1, float val2)
//
// It propagates NaN inputs back to the caller and
// otherwise returns the input with a lesser magnitude.
// It treats +0 as lesser than -0 as per the specification.
// It treats +0 as greater than -0 as per the specification.
//
// Arguments:
// x - left operand
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public UnixImplementation(int elementCount)

public override bool IsReadonly => false;

public override int Length => _elementCount;

public override Memory<T> Memory => _memoryManager.Memory;

public override Span<T> Span
Expand Down Expand Up @@ -83,10 +85,7 @@ protected override void Dispose(bool disposing)
// no-op; the handle will be disposed separately
}

public override Span<T> GetSpan()
{
throw new NotImplementedException();
}
public override Span<T> GetSpan() => _impl.Span;

public override MemoryHandle Pin(int elementIndex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ internal WindowsImplementation(VirtualAllocHandle handle, int byteOffsetIntoHand

public override bool IsReadonly => (Protection != VirtualAllocProtection.PAGE_READWRITE);

public override int Length => _elementCount;

internal VirtualAllocProtection Protection
{
get
Expand Down Expand Up @@ -189,10 +191,7 @@ protected override void Dispose(bool disposing)
// no-op; the handle will be disposed separately
}

public override Span<T> GetSpan()
{
throw new NotImplementedException();
}
public override Span<T> GetSpan() => _impl.Span;

public override MemoryHandle Pin(int elementIndex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public abstract class BoundedMemory<T> : IDisposable where T : unmanaged
/// </summary>
public abstract bool IsReadonly { get; }

/// <summary>Gets the length of the <see cref="BoundedMemory{T}"/> instance.</summary>
public abstract int Length { get; }

/// <summary>
/// Gets the <see cref="Memory{Byte}"/> which represents this native memory.
/// This <see cref="BoundedMemory{T}"/> instance must be kept alive while working with the <see cref="Memory{Byte}"/>.
Expand Down Expand Up @@ -44,5 +47,23 @@ public abstract class BoundedMemory<T> : IDisposable where T : unmanaged
/// OS does not support marking the memory block as read+write.
/// </summary>
public abstract void MakeWriteable();

/// <summary>
/// Gets the <see cref="Span{Byte}"/> which represents this native memory.
/// This <see cref="BoundedMemory{T}"/> instance must be kept alive while working with the <see cref="Span{Byte}"/>.
/// </summary>
public static implicit operator Span<T>(BoundedMemory<T> boundedMemory) => boundedMemory.Span;

/// <summary>
/// Gets the <see cref="ReadOnlySpan{Byte}"/> which represents this native memory.
/// This <see cref="BoundedMemory{T}"/> instance must be kept alive while working with the <see cref="ReadOnlySpan{Byte}"/>.
/// </summary>
public static implicit operator ReadOnlySpan<T>(BoundedMemory<T> boundedMemory) => boundedMemory.Span;

/// <summary>
/// Gets a reference to the element at the specified index.
/// This <see cref="BoundedMemory{T}"/> instance must be kept alive while working with the reference.
/// </summary>
public ref T this[int index] => ref Span[index];
}
}
74 changes: 74 additions & 0 deletions src/libraries/Microsoft.Bcl.Numerics/Microsoft.Bcl.Numerics.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{CAEE0409-CCC3-4EA6-AB54-177FD305D42D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bcl.Numerics", "ref\Microsoft.Bcl.Numerics.csproj", "{73E7C25C-AEBC-4F4F-B8D1-0CC49D5B92DE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bcl.Numerics", "src\Microsoft.Bcl.Numerics.csproj", "{4D4BED71-8904-4A74-88CD-63D002CCACD0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Bcl.Numerics.Tests", "tests\Microsoft.Bcl.Numerics.Tests.csproj", "{51D9518A-464D-4257-9567-3BDCFF24F3EE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComInterfaceGenerator", "..\System.Runtime.InteropServices\gen\ComInterfaceGenerator\ComInterfaceGenerator.csproj", "{E30F71EB-6C3B-4052-84F7-36EAA178A45E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibraryImportGenerator", "..\System.Runtime.InteropServices\gen\LibraryImportGenerator\LibraryImportGenerator.csproj", "{0AE44453-273B-4F0E-9901-A87891A73C1B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.SourceGeneration", "..\System.Runtime.InteropServices\gen\Microsoft.Interop.SourceGeneration\Microsoft.Interop.SourceGeneration.csproj", "{D0F1936C-CF7C-4448-9F90-B9DEABE89EBB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{6614EF7F-23FC-4809-AFF5-1ADBF1B6422C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{111B1B5B-A004-4C05-9A8C-E0931DADA5FB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{85204CF5-0C88-4BBB-9E70-D8CCED82ED3D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{D6A9108E-553B-445E-A037-FA4F3140A279}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CAEE0409-CCC3-4EA6-AB54-177FD305D42D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CAEE0409-CCC3-4EA6-AB54-177FD305D42D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CAEE0409-CCC3-4EA6-AB54-177FD305D42D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CAEE0409-CCC3-4EA6-AB54-177FD305D42D}.Release|Any CPU.Build.0 = Release|Any CPU
{73E7C25C-AEBC-4F4F-B8D1-0CC49D5B92DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{73E7C25C-AEBC-4F4F-B8D1-0CC49D5B92DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{73E7C25C-AEBC-4F4F-B8D1-0CC49D5B92DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{73E7C25C-AEBC-4F4F-B8D1-0CC49D5B92DE}.Release|Any CPU.Build.0 = Release|Any CPU
{4D4BED71-8904-4A74-88CD-63D002CCACD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D4BED71-8904-4A74-88CD-63D002CCACD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D4BED71-8904-4A74-88CD-63D002CCACD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D4BED71-8904-4A74-88CD-63D002CCACD0}.Release|Any CPU.Build.0 = Release|Any CPU
{51D9518A-464D-4257-9567-3BDCFF24F3EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51D9518A-464D-4257-9567-3BDCFF24F3EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51D9518A-464D-4257-9567-3BDCFF24F3EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51D9518A-464D-4257-9567-3BDCFF24F3EE}.Release|Any CPU.Build.0 = Release|Any CPU
{E30F71EB-6C3B-4052-84F7-36EAA178A45E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E30F71EB-6C3B-4052-84F7-36EAA178A45E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E30F71EB-6C3B-4052-84F7-36EAA178A45E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E30F71EB-6C3B-4052-84F7-36EAA178A45E}.Release|Any CPU.Build.0 = Release|Any CPU
{0AE44453-273B-4F0E-9901-A87891A73C1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0AE44453-273B-4F0E-9901-A87891A73C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0AE44453-273B-4F0E-9901-A87891A73C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0AE44453-273B-4F0E-9901-A87891A73C1B}.Release|Any CPU.Build.0 = Release|Any CPU
{D0F1936C-CF7C-4448-9F90-B9DEABE89EBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D0F1936C-CF7C-4448-9F90-B9DEABE89EBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0F1936C-CF7C-4448-9F90-B9DEABE89EBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0F1936C-CF7C-4448-9F90-B9DEABE89EBB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{CAEE0409-CCC3-4EA6-AB54-177FD305D42D} = {6614EF7F-23FC-4809-AFF5-1ADBF1B6422C}
{51D9518A-464D-4257-9567-3BDCFF24F3EE} = {6614EF7F-23FC-4809-AFF5-1ADBF1B6422C}
{73E7C25C-AEBC-4F4F-B8D1-0CC49D5B92DE} = {111B1B5B-A004-4C05-9A8C-E0931DADA5FB}
{4D4BED71-8904-4A74-88CD-63D002CCACD0} = {85204CF5-0C88-4BBB-9E70-D8CCED82ED3D}
{E30F71EB-6C3B-4052-84F7-36EAA178A45E} = {D6A9108E-553B-445E-A037-FA4F3140A279}
{0AE44453-273B-4F0E-9901-A87891A73C1B} = {D6A9108E-553B-445E-A037-FA4F3140A279}
{D0F1936C-CF7C-4448-9F90-B9DEABE89EBB} = {D6A9108E-553B-445E-A037-FA4F3140A279}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A835CEDB-E9E2-49EE-8499-BD7FDD984E53}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.MathF))]
42 changes: 42 additions & 0 deletions src/libraries/Microsoft.Bcl.Numerics/ref/Microsoft.Bcl.Numerics.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// ------------------------------------------------------------------------------
// Changes to this file must follow the https://aka.ms/api-review process.
// ------------------------------------------------------------------------------

namespace System
{
public static partial class MathF
{
public const float E = 2.7182817f;
public const float PI = 3.1415927f;
public static float Abs(float x) { throw null; }
public static float Acos(float x) { throw null; }
public static float Asin(float x) { throw null; }
public static float Atan(float x) { throw null; }
public static float Atan2(float y, float x) { throw null; }
public static float Ceiling(float x) { throw null; }
public static float Cos(float x) { throw null; }
public static float Cosh(float x) { throw null; }
public static float Exp(float x) { throw null; }
public static float Floor(float x) { throw null; }
public static float IEEERemainder(float x, float y) { throw null; }
public static float Log(float x) { throw null; }
public static float Log(float x, float y) { throw null; }
public static float Log10(float x) { throw null; }
public static float Max(float x, float y) { throw null; }
public static float Min(float x, float y) { throw null; }
public static float Pow(float x, float y) { throw null; }
public static float Round(float x) { throw null; }
public static float Round(float x, int digits) { throw null; }
public static float Round(float x, int digits, System.MidpointRounding mode) { throw null; }
public static float Round(float x, System.MidpointRounding mode) { throw null; }
public static int Sign(float x) { throw null; }
public static float Sin(float x) { throw null; }
public static float Sinh(float x) { throw null; }
public static float Sqrt(float x) { throw null; }
public static float Tan(float x) { throw null; }
public static float Tanh(float x) { throw null; }
public static float Truncate(float x) { throw null; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;$(NetFrameworkMinimum);netstandard2.1</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
<Compile Include="Microsoft.Bcl.Numerics.cs" Condition="'$(TargetFramework)' != 'netstandard2.1'" />
<Compile Include="Microsoft.Bcl.Numerics.Forwards.cs" Condition="'$(TargetFramework)' == 'netstandard2.1'" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;$(NetFrameworkMinimum);netstandard2.1</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsPackable>true</IsPackable>

<!-- This assembly should never be placed inbox as it is only for downlevel compatibility. -->
<PackageDescription>Provides the System.MathF for .NET Standard 2.0</PackageDescription>
<!-- Disabling baseline validation since this is a brand new package.
Once this package has shipped a stable version, the following line
should be removed in order to re-enable validation. -->
<DisablePackageBaselineValidation>true</DisablePackageBaselineValidation>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' != 'netstandard2.1'">
<Compile Include="System\MathF.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
<Compile Include="System\Microsoft.Bcl.Numerics.Forwards.cs" />
</ItemGroup>

</Project>
2 changes: 0 additions & 2 deletions src/libraries/Microsoft.Bcl.Numerics/src/PACKAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ As of .NET Core 2.0 and .NET Standard 2.1, the C# language has support for math

## How to Use

<!-- A compelling example on how to use this package with code, as well as any specific guidelines for when to use the package -->

```C#
using System;

Expand Down

0 comments on commit 4b7c754

Please sign in to comment.