Skip to content

Commit ac4fead

Browse files
briancyluieerhardt
authored andcommitted
Port C# hardware intrinsics APIs for SSE from SIMD native algorithms (#562)
* Implemented SSE support and software fallbacks for key intrinsics * Implemented unit tests for key intrinsics with passing results * Implemented performance tests on some key intrinsics with BenchmarkDotNet * Fixed array pinning issues and solved unreported latency of NativeDotSU * Minor syntax change for style consistency in fixed statements * Implemented performance tests for all key intrinsics * Simulated user performance with large inputs * Allow CpuMath to reference C# Hardware Intrinsics APIs. Need to multi-target CpuMath for netstandard and netcoreapp2.1. Also, since we are going to move CpuMath into its own NuGet package, remove the dependency from CpuMath to the ML.Core project. * Added files for the hierarchical framework to prepare for multi-targetting. Note: It will not compile until Microsoft.ML.CpuMath.csproj is changed to adapt to multi-targetting. * Removed the redundant CpuMathUtils.cs file. * Cleaned up the primitive build constant for featuring intrinsics * Created a new helper class holding C# implementations of SSE intrinsics to simplify CpuMathUtils.DotNetCoreApp.cs * Minor change in naming of variables * Implemented more SSE intrinsics * Changed version number of .NET Core App as target framework * Cleaned up unit test file that needs to be split into two for multi-targeting * Fixed seed in performance tests * Cleaned up unreferenced namespaces * Split unit tests into two projects for multi-targetting * Cleaned up new intrinsics that are not yet tested to prepare for PR * Minor style changes * Added the solution package that includes multi-targeting with UseIntrinsics attribute * Included all files in the CpuMath project for display in Visual Studio regardless of target framework * Removed irrelevant build line from CpuMath - due to working in Mac OSX * Response to PR review * Removed deprecated src\Native\CpuMath working folder * Removed unnecessary references in unit tests * Minor style changes * Fixed SLN file * Fixed build error with netcoreapp3.0 not supported * Minor style fixes * Skip netcoreapp3.0 projects when not building for intrinsics * Exclude netcoreapp3.0 tests from running by overriding VSTest target * Second response to PR feedback * Removed NETCoreAppMaximumVersion tags with modification * Moved VSTest targets to Empty.targets, and parsed -Intrinsics configs for Native build * Modified VectorSum to fix perf results * Modified VectorSum to comply with latest C# language updates * Response to PR feedback: added a comment and removed unnecessary MSBuild tags * Made private functions for SSE intrinsics inline
1 parent eadc353 commit ac4fead

20 files changed

+1639
-8
lines changed

Directory.Build.props

+7
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,11 @@
114114
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
115115
</PropertyGroup>
116116

117+
<PropertyGroup>
118+
<UseIntrinsics Condition="'$(UseIntrinsics)' == ''">$(Configuration.EndsWith('-Intrinsics'))</UseIntrinsics>
119+
</PropertyGroup>
120+
121+
<PropertyGroup>
122+
<CustomAfterMicrosoftCommonTargets>$(RepoRoot)build\AfterCommonTargets.targets</CustomAfterMicrosoftCommonTargets>
123+
</PropertyGroup>
117124
</Project>

Microsoft.ML.sln

+34
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.CodeAnalyzer",
9797
EndProject
9898
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.CodeAnalyzer.Tests", "test\Microsoft.ML.CodeAnalyzer.Tests\Microsoft.ML.CodeAnalyzer.Tests.csproj", "{3E4ABF07-7970-4BE6-B45B-A13D3C397545}"
9999
EndProject
100+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.CpuMath.PerformanceTests", "test\Microsoft.ML.CpuMath.PerformanceTests\Microsoft.ML.CpuMath.PerformanceTests.csproj", "{7333EDEF-4144-405C-A5EC-6F42201857D8}"
101+
EndProject
102+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.CpuMath.UnitTests.netstandard", "test\Microsoft.ML.CpuMath.UnitTests.netstandard\Microsoft.ML.CpuMath.UnitTests.netstandard.csproj", "{A0E562A9-0E6D-470D-B180-6EB44BA84D60}"
103+
EndProject
104+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.CpuMath.UnitTests.netcoreapp", "test\Microsoft.ML.CpuMath.UnitTests.netcoreapp\Microsoft.ML.CpuMath.UnitTests.netcoreapp.csproj", "{5F81A2A4-73AD-494C-B387-07D605EC8826}"
105+
EndProject
106+
100107
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Microsoft.ML.FSharp.Tests", "test\Microsoft.ML.FSharp.Tests\Microsoft.ML.FSharp.Tests.fsproj", "{802233D6-8CC0-46AD-9F23-FEE1E9AED9B3}"
101108
EndProject
102109
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ML.ImageAnalytics", "src\Microsoft.ML.ImageAnalytics\Microsoft.ML.ImageAnalytics.csproj", "{00E38F77-1E61-4CDF-8F97-1417D4E85053}"
@@ -335,6 +342,30 @@ Global
335342
{3E4ABF07-7970-4BE6-B45B-A13D3C397545}.Release|Any CPU.Build.0 = Release|Any CPU
336343
{3E4ABF07-7970-4BE6-B45B-A13D3C397545}.Release-Intrinsics|Any CPU.ActiveCfg = Release|Any CPU
337344
{3E4ABF07-7970-4BE6-B45B-A13D3C397545}.Release-Intrinsics|Any CPU.Build.0 = Release|Any CPU
345+
{7333EDEF-4144-405C-A5EC-6F42201857D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
346+
{7333EDEF-4144-405C-A5EC-6F42201857D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
347+
{7333EDEF-4144-405C-A5EC-6F42201857D8}.Debug-Intrinsics|Any CPU.ActiveCfg = Debug|Any CPU
348+
{7333EDEF-4144-405C-A5EC-6F42201857D8}.Debug-Intrinsics|Any CPU.Build.0 = Debug|Any CPU
349+
{7333EDEF-4144-405C-A5EC-6F42201857D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
350+
{7333EDEF-4144-405C-A5EC-6F42201857D8}.Release|Any CPU.Build.0 = Release|Any CPU
351+
{7333EDEF-4144-405C-A5EC-6F42201857D8}.Release-Intrinsics|Any CPU.ActiveCfg = Release|Any CPU
352+
{7333EDEF-4144-405C-A5EC-6F42201857D8}.Release-Intrinsics|Any CPU.Build.0 = Release|Any CPU
353+
{A0E562A9-0E6D-470D-B180-6EB44BA84D60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
354+
{A0E562A9-0E6D-470D-B180-6EB44BA84D60}.Debug|Any CPU.Build.0 = Debug|Any CPU
355+
{A0E562A9-0E6D-470D-B180-6EB44BA84D60}.Debug-Intrinsics|Any CPU.ActiveCfg = Debug|Any CPU
356+
{A0E562A9-0E6D-470D-B180-6EB44BA84D60}.Debug-Intrinsics|Any CPU.Build.0 = Debug|Any CPU
357+
{A0E562A9-0E6D-470D-B180-6EB44BA84D60}.Release|Any CPU.ActiveCfg = Release|Any CPU
358+
{A0E562A9-0E6D-470D-B180-6EB44BA84D60}.Release|Any CPU.Build.0 = Release|Any CPU
359+
{A0E562A9-0E6D-470D-B180-6EB44BA84D60}.Release-Intrinsics|Any CPU.ActiveCfg = Release|Any CPU
360+
{A0E562A9-0E6D-470D-B180-6EB44BA84D60}.Release-Intrinsics|Any CPU.Build.0 = Release|Any CPU
361+
{5F81A2A4-73AD-494C-B387-07D605EC8826}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
362+
{5F81A2A4-73AD-494C-B387-07D605EC8826}.Debug|Any CPU.Build.0 = Debug|Any CPU
363+
{5F81A2A4-73AD-494C-B387-07D605EC8826}.Debug-Intrinsics|Any CPU.ActiveCfg = Debug|Any CPU
364+
{5F81A2A4-73AD-494C-B387-07D605EC8826}.Debug-Intrinsics|Any CPU.Build.0 = Debug|Any CPU
365+
{5F81A2A4-73AD-494C-B387-07D605EC8826}.Release|Any CPU.ActiveCfg = Release|Any CPU
366+
{5F81A2A4-73AD-494C-B387-07D605EC8826}.Release|Any CPU.Build.0 = Release|Any CPU
367+
{5F81A2A4-73AD-494C-B387-07D605EC8826}.Release-Intrinsics|Any CPU.ActiveCfg = Release|Any CPU
368+
{5F81A2A4-73AD-494C-B387-07D605EC8826}.Release-Intrinsics|Any CPU.Build.0 = Release|Any CPU
338369
{802233D6-8CC0-46AD-9F23-FEE1E9AED9B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
339370
{802233D6-8CC0-46AD-9F23-FEE1E9AED9B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
340371
{802233D6-8CC0-46AD-9F23-FEE1E9AED9B3}.Debug-Intrinsics|Any CPU.ActiveCfg = Debug|Any CPU
@@ -395,6 +426,9 @@ Global
395426
{001F3B4E-FBE4-4001-AFD2-A6A989CD1C25} = {09EADF06-BE25-4228-AB53-95AE3E15B530}
396427
{DCF46B79-1FDB-4DBA-A263-D3D64E3AAA27} = {09EADF06-BE25-4228-AB53-95AE3E15B530}
397428
{BF66A305-DF10-47E4-8D81-42049B149D2B} = {D3D38B03-B557-484D-8348-8BADEE4DF592}
429+
{7333EDEF-4144-405C-A5EC-6F42201857D8} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4}
430+
{A0E562A9-0E6D-470D-B180-6EB44BA84D60} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4}
431+
{5F81A2A4-73AD-494C-B387-07D605EC8826} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4}
398432
{B4E55B2D-2A92-46E7-B72F-E76D6FD83440} = {7F13E156-3EBA-4021-84A5-CD56BA72F99E}
399433
{3E4ABF07-7970-4BE6-B45B-A13D3C397545} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4}
400434
{802233D6-8CC0-46AD-9F23-FEE1E9AED9B3} = {AED9C836-31E3-4F3F-8ABC-929555D3F3C4}

build.proj

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
<Target Name="RestoreProjects" Condition="'$(RestoreDuringBuild)'=='true'">
4242
<Message Importance="High" Text="Restoring all projects..." />
4343
<MSBuild Projects="@(Project)"
44-
Targets="Restore" />
44+
Targets="Restore"
45+
Properties="MSBuildWarningsAsMessages=NU1503" />
4546
</Target>
4647

4748
<Target Name="BuildNative"

build/AfterCommonTargets.targets

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project>
2+
<PropertyGroup>
3+
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
4+
</PropertyGroup>
5+
6+
<!--
7+
We use netcoreapp3.0 for C# intrinsics, but 3.0 isn't supported in CI or in normal development
8+
environments yet. So when we are targeting netcoreapp3.0, but aren't building for intrinsics,
9+
we need to skip the project.
10+
-->
11+
<Import Condition="'$(UseIntrinsics)' != 'true' and '$(TargetFramework)' == 'netcoreapp3.0'"
12+
Project="$(RepoRoot)build\Empty.targets" />
13+
</Project>

build/Empty.targets

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project>
2+
<PropertyGroup>
3+
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
4+
<!--
5+
In the SDK ImportAfter folder, this property is declared to point to Microsoft.TestPlatform.targets, which is the file containing the original VSTest target.
6+
Since the Microsoft.TestPlatform.targets are in the ImportAfter folder, they would be imported after this file hence our empty VSTest target would be overriden,
7+
in order to be able to override this target, we set the VSTestTargets property to an inexistent file path, so nothing will be imported and that way we successfully
8+
overrode the VSTest target.
9+
-->
10+
<VSTestTargets>ignore.targets</VSTestTargets>
11+
</PropertyGroup>
12+
13+
<!--
14+
Copied from https://github.com/dotnet/arcade/blob/master/src/Microsoft.DotNet.Arcade.Sdk/tools/Empty.targets
15+
16+
Import this file to suppress all targets while allowing the project to participate in the build.
17+
Workaround for https://github.com/dotnet/sdk/issues/2071.
18+
19+
The targets defined here are not sufficient for the project to be open in Visual Studio without issues though.
20+
-->
21+
22+
<Target Name="_IsProjectRestoreSupported"/>
23+
<Target Name="_CheckForInvalidConfigurationAndPlatform"/>
24+
<Target Name="Restore"/>
25+
<Target Name="Build"/>
26+
<Target Name="Test"/>
27+
<Target Name="VSTest"/>
28+
<Target Name="Pack"/>
29+
</Project>

0 commit comments

Comments
 (0)