Skip to content

Commit e56d52d

Browse files
authored
[release/7.0][wasm] SIMD related build fixes (#75042)
- rename `$(WasmSIMD)` -> `$(WasmEnableSIMD)` - Require the workload when the property is set - Add tests for the various cases
1 parent 9dda765 commit e56d52d

File tree

6 files changed

+125
-27
lines changed

6 files changed

+125
-27
lines changed

eng/testing/scenarios/BuildWasmAppsJobsList.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Wasm.Build.Tests.RebuildTests
1717
Wasm.Build.Tests.SatelliteAssembliesTests
1818
Wasm.Build.Tests.WasmBuildAppTest
1919
Wasm.Build.Tests.WasmNativeDefaultsTests
20-
Wasm.Build.Tests.WorkloadTests
2120
Wasm.Build.Tests.WasmRunOutOfAppBundleTests
21+
Wasm.Build.Tests.WasmSIMDTests
2222
Wasm.Build.Tests.WasmTemplateTests
23+
Wasm.Build.Tests.WorkloadTests
24+

src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.net7.Manifest/WorkloadManifest.targets.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
<PropertyGroup Condition="'$(TargetsNet7)' == 'true' and '$(RuntimeIdentifier)' == 'browser-wasm' AND '$(UsingBrowserRuntimeWorkload)' == ''">
2424
<!-- $(WasmBuildNative)==true is needed to enable workloads, when using native references, without AOT -->
25-
<UsingBrowserRuntimeWorkload Condition="'$(RunAOTCompilation)' == 'true' or '$(WasmBuildNative)' == 'true' or '$(WasmGenerateAppBundle)' == 'true' or '$(UsingMicrosoftNETSdkBlazorWebAssembly)' != 'true'" >true</UsingBrowserRuntimeWorkload>
25+
<UsingBrowserRuntimeWorkload Condition="'$(RunAOTCompilation)' == 'true' or '$(WasmEnableSIMD)' == 'true' or '$(WasmBuildNative)' == 'true' or '$(WasmGenerateAppBundle)' == 'true' or '$(UsingMicrosoftNETSdkBlazorWebAssembly)' != 'true'" >true</UsingBrowserRuntimeWorkload>
2626
<UsingBrowserRuntimeWorkload Condition="'$(UsingBrowserRuntimeWorkload)' == ''" >$(WasmNativeWorkload7)</UsingBrowserRuntimeWorkload>
2727
</PropertyGroup>
2828

src/mono/wasm/build/WasmApp.Native.targets

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@
108108
<!-- build AOT, only if explicitly requested -->
109109
<WasmBuildNative Condition="'$(RunAOTCompilation)' == 'true' and '$(RunAOTCompilationAfterBuild)' == 'true'">true</WasmBuildNative>
110110

111+
<WasmBuildNative Condition="'$(WasmBuildNative)' == '' and '$(WasmEnableSIMD)' == 'true'">true</WasmBuildNative>
112+
111113
<WasmBuildNative Condition="'$(WasmBuildNative)' == '' and @(NativeFileReference->Count()) > 0" >true</WasmBuildNative>
112114

113115
<WasmBuildNative Condition="'$(WasmBuildNative)' == ''">false</WasmBuildNative>
@@ -118,6 +120,7 @@
118120
<!-- AOT==true overrides WasmBuildNative -->
119121
<WasmBuildNative Condition="'$(RunAOTCompilation)' == 'true'">true</WasmBuildNative>
120122
<WasmBuildNative Condition="'$(WasmBuildNative)' == '' and @(NativeFileReference->Count()) > 0" >true</WasmBuildNative>
123+
<WasmBuildNative Condition="'$(WasmBuildNative)' == '' and '$(WasmEnableSIMD)' == 'true'">true</WasmBuildNative>
121124

122125
<!-- not aot, not trimmed app, no reason to relink -->
123126
<WasmBuildNative Condition="'$(WasmBuildNative)' == '' and '$(PublishTrimmed)' != 'true'">false</WasmBuildNative>
@@ -195,7 +198,7 @@
195198
<_EmccCommonFlags Include="-v" Condition="'$(EmccVerbose)' != 'false'" />
196199
<_EmccCommonFlags Include="-s DISABLE_EXCEPTION_CATCHING=0" Condition="'$(WasmExceptionHandling)' == 'false'" />
197200
<_EmccCommonFlags Include="-fwasm-exceptions" Condition="'$(WasmExceptionHandling)' == 'true'" />
198-
<_EmccCommonFlags Include="-msimd128" Condition="'$(WasmSIMD)' == 'true'" />
201+
<_EmccCommonFlags Include="-msimd128" Condition="'$(WasmEnableSIMD)' == 'true'" />
199202

200203
<_EmccIncludePaths Include="$(_WasmIntermediateOutputPath.TrimEnd('\/'))" />
201204
<_EmccIncludePaths Include="$(_WasmRuntimePackIncludeDir)mono-2.0" />
@@ -524,7 +527,7 @@
524527
<MonoAOTCompilerDefaultAotArguments Include="static" />
525528
<MonoAOTCompilerDefaultAotArguments Include="direct-icalls" />
526529
<MonoAOTCompilerDefaultAotArguments Include="deterministic" />
527-
<MonoAOTCompilerDefaultAotArguments Include="mattr=simd" Condition="'$(WasmSIMD)' == 'true'" />
530+
<MonoAOTCompilerDefaultAotArguments Include="mattr=simd" Condition="'$(WasmEnableSIMD)' == 'true'" />
528531
<MonoAOTCompilerDefaultProcessArguments Include="--wasm-exceptions" Condition="'$(WasmExceptionHandling)' == 'true'" />
529532
<MonoAOTCompilerDefaultProcessArguments Include="--wasm-gc-safepoints" Condition="'$(WasmEnableThreads)' == 'true' or '$(WasmEnablePerfTracing)' == 'true'" />
530533
<AotProfilePath Include="$(WasmAotProfilePath)"/>

src/mono/wasm/build/WasmApp.targets

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
Defaults to false.
6767
- $(WasmAotProfilePath) - Path to an AOT profile file.
6868
- $(WasmExceptionHandling) - Enable support for the WASM Exception Handling feature.
69-
- $(WasmSIMD) - Enable support for the WASM SIMD feature.
69+
- $(WasmEnableSIMD) - Enable support for the WASM SIMD feature.
7070
7171
Public items:
7272
- @(WasmExtraFilesToDeploy) - Files to copy to $(WasmAppDir).
@@ -87,7 +87,7 @@
8787
<PropertyGroup>
8888
<WasmDedup Condition="'$(WasmDedup)' == ''">false</WasmDedup>
8989
<WasmExceptionHandling Condition="'$(WasmExceptionHandling)' == ''">false</WasmExceptionHandling>
90-
<WasmSIMD Condition="'$(WasmSIMD)' == ''">false</WasmSIMD>
90+
<WasmEnableSIMD Condition="'$(WasmEnableSIMD)' == ''">false</WasmEnableSIMD>
9191

9292
<!--<WasmStripAOTAssemblies Condition="'$(AOTMode)' == 'LLVMOnlyInterp'">false</WasmStripAOTAssemblies>-->
9393
<!--<WasmStripAOTAssemblies Condition="'$(WasmStripAOTAssemblies)' == ''">$(RunAOTCompilation)</WasmStripAOTAssemblies>-->

src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ protected string RunAndTestWasmApp(BuildArgs buildArgs,
137137
Dictionary<string, string>? envVars = null,
138138
string targetFramework = DefaultTargetFramework,
139139
string? extraXHarnessMonoArgs = null,
140+
string? extraXHarnessArgs = null,
140141
string jsRelativePath = "test-main.js")
141142
{
142143
buildDir ??= _projectDir;
@@ -159,13 +160,15 @@ protected string RunAndTestWasmApp(BuildArgs buildArgs,
159160
throw new InvalidOperationException("Running tests with V8 on windows isn't supported");
160161

161162
// Use wasm-console.log to get the xharness output for non-browser cases
162-
(string testCommand, string extraXHarnessArgs, bool useWasmConsoleOutput) = host switch
163+
(string testCommand, string xharnessArgs, bool useWasmConsoleOutput) = host switch
163164
{
164165
RunHost.V8 => ("wasm test", $"--js-file={jsRelativePath} --engine=V8 -v trace", true),
165166
RunHost.NodeJS => ("wasm test", $"--js-file={jsRelativePath} --engine=NodeJS -v trace", true),
166167
_ => ("wasm test-browser", $"-v trace -b {host} --web-server-use-cop", false)
167168
};
168169

170+
extraXHarnessArgs += " " + xharnessArgs;
171+
169172
string testLogPath = Path.Combine(_logPath, host.ToString());
170173
string output = RunWithXHarness(
171174
testCommand,
Lines changed: 110 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.IO;
45
using Xunit;
56
using Xunit.Abstractions;
67

@@ -16,25 +17,114 @@ public WasmSIMDTests(ITestOutputHelper output, SharedBuildPerTestClassFixture bu
1617
}
1718

1819
[Theory]
19-
[MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true, RunHost.All })]
20-
public void BuildWithSIMD(BuildArgs buildArgs, RunHost host, string id)
21-
=> TestMain("main_simd_aot",
22-
@"
23-
using System;
24-
using System.Runtime.Intrinsics;
25-
26-
public class TestClass {
27-
public static int Main()
28-
{
29-
var v1 = Vector128.Create(0x12345678);
30-
var v2 = Vector128.Create(0x23456789);
31-
var v3 = v1*v2;
32-
Console.WriteLine(v3);
33-
Console.WriteLine(""Hello, World!"");
34-
35-
return 42;
36-
}
37-
}",
38-
buildArgs, host, id, extraProperties: "<WasmSIMD>true</WasmSIMD>");
20+
[MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ false, RunHost.All })]
21+
public void BuildWithSIMD_NoAOT_ShouldRelink(BuildArgs buildArgs, RunHost host, string id)
22+
{
23+
string projectName = $"sim_with_workload_no_aot";
24+
buildArgs = buildArgs with { ProjectName = projectName };
25+
buildArgs = ExpandBuildArgs(buildArgs, "<WasmEnableSIMD>true</WasmEnableSIMD>");
26+
27+
(_, string output) = BuildProject(buildArgs,
28+
id: id,
29+
new BuildProjectOptions(
30+
InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_simdProgramText),
31+
Publish: false,
32+
DotnetWasmFromRuntimePack: false));
33+
34+
if (!_buildContext.TryGetBuildFor(buildArgs, out _))
35+
{
36+
// Check if this is not a cached build
37+
Assert.Contains("Compiling native assets with excc", output);
38+
}
39+
40+
RunAndTestWasmApp(buildArgs,
41+
extraXHarnessArgs: host == RunHost.NodeJS ? "--engine-arg=--experimental-wasm-simd" : "",
42+
expectedExitCode: 42,
43+
test: output =>
44+
{
45+
Assert.Contains("<-2094756296, -2094756296, -2094756296, -2094756296>", output);
46+
Assert.Contains("Hello, World!", output);
47+
}, host: host, id: id);
48+
}
49+
50+
[Theory]
51+
// https://github.com/dotnet/runtime/issues/75044 - disabled for V8, and NodeJS
52+
//[MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true, RunHost.All })]
53+
[MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true, RunHost.Chrome })]
54+
[MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ false, RunHost.All })]
55+
public void PublishWithSIMD_AOT(BuildArgs buildArgs, RunHost host, string id)
56+
{
57+
string projectName = $"sim_with_workload_aot";
58+
buildArgs = buildArgs with { ProjectName = projectName };
59+
buildArgs = ExpandBuildArgs(buildArgs, "<WasmEnableSIMD>true</WasmEnableSIMD>");
60+
61+
BuildProject(buildArgs,
62+
id: id,
63+
new BuildProjectOptions(
64+
InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_simdProgramText),
65+
DotnetWasmFromRuntimePack: false));
66+
67+
RunAndTestWasmApp(buildArgs,
68+
extraXHarnessArgs: host == RunHost.NodeJS ? "--engine-arg=--experimental-wasm-simd" : "",
69+
expectedExitCode: 42,
70+
test: output =>
71+
{
72+
Assert.Contains("<-2094756296, -2094756296, -2094756296, -2094756296>", output);
73+
Assert.Contains("Hello, World!", output);
74+
}, host: host, id: id);
75+
}
76+
77+
[Theory, TestCategory("no-workload")]
78+
[InlineData("Debug", /*aot*/true, /*publish*/true)]
79+
[InlineData("Debug", /*aot*/false, /*publish*/false)]
80+
[InlineData("Debug", /*aot*/false, /*publish*/true)]
81+
[InlineData("Release", /*aot*/true, /*publish*/true)]
82+
[InlineData("Release", /*aot*/false, /*publish*/false)]
83+
[InlineData("Release", /*aot*/false, /*publish*/true)]
84+
public void BuildWithSIMDNeedsWorkload(string config, bool aot, bool publish)
85+
{
86+
string id = Path.GetRandomFileName();
87+
string projectName = $"simd_no_workload_{config}_aot_{aot}";
88+
BuildArgs buildArgs = new
89+
(
90+
ProjectName: projectName,
91+
Config: config,
92+
AOT: aot,
93+
ProjectFileContents: "placeholder",
94+
ExtraBuildArgs: string.Empty
95+
);
96+
97+
string extraProperties = """
98+
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
99+
<WasmEnableSIMD>true</WasmEnableSIMD>
100+
""";
101+
buildArgs = ExpandBuildArgs(buildArgs, extraProperties);
102+
103+
(_, string output) = BuildProject(buildArgs,
104+
id: id,
105+
new BuildProjectOptions(
106+
InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_simdProgramText),
107+
Publish: publish,
108+
ExpectSuccess: false,
109+
UseCache: false));
110+
Assert.Contains("following workloads must be installed: wasm-tools", output);
111+
}
112+
113+
private static string s_simdProgramText = @"
114+
using System;
115+
using System.Runtime.Intrinsics;
116+
117+
public class TestClass {
118+
public static int Main()
119+
{
120+
var v1 = Vector128.Create(0x12345678);
121+
var v2 = Vector128.Create(0x23456789);
122+
var v3 = v1*v2;
123+
Console.WriteLine(v3);
124+
Console.WriteLine(""Hello, World!"");
125+
126+
return 42;
127+
}
128+
}";
39129
}
40130
}

0 commit comments

Comments
 (0)