diff --git a/eng/testing/scenarios/BuildWasmAppsJobsList.txt b/eng/testing/scenarios/BuildWasmAppsJobsList.txt index bbbca109e575c1..7a92f4e164eb3d 100644 --- a/eng/testing/scenarios/BuildWasmAppsJobsList.txt +++ b/eng/testing/scenarios/BuildWasmAppsJobsList.txt @@ -17,6 +17,8 @@ Wasm.Build.Tests.RebuildTests Wasm.Build.Tests.SatelliteAssembliesTests Wasm.Build.Tests.WasmBuildAppTest Wasm.Build.Tests.WasmNativeDefaultsTests -Wasm.Build.Tests.WorkloadTests Wasm.Build.Tests.WasmRunOutOfAppBundleTests +Wasm.Build.Tests.WasmSIMDTests Wasm.Build.Tests.WasmTemplateTests +Wasm.Build.Tests.WorkloadTests + diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.net7.Manifest/WorkloadManifest.targets.in b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.net7.Manifest/WorkloadManifest.targets.in index c6b512e6c45165..d4c5d59bc2ae30 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.net7.Manifest/WorkloadManifest.targets.in +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.net7.Manifest/WorkloadManifest.targets.in @@ -22,7 +22,7 @@ - true + true $(WasmNativeWorkload7) diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index dfe3a169d5604b..4c624331712115 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -108,6 +108,8 @@ true + true + true false @@ -118,6 +120,7 @@ true true + true false @@ -195,7 +198,7 @@ <_EmccCommonFlags Include="-v" Condition="'$(EmccVerbose)' != 'false'" /> <_EmccCommonFlags Include="-s DISABLE_EXCEPTION_CATCHING=0" Condition="'$(WasmExceptionHandling)' == 'false'" /> <_EmccCommonFlags Include="-fwasm-exceptions" Condition="'$(WasmExceptionHandling)' == 'true'" /> - <_EmccCommonFlags Include="-msimd128" Condition="'$(WasmSIMD)' == 'true'" /> + <_EmccCommonFlags Include="-msimd128" Condition="'$(WasmEnableSIMD)' == 'true'" /> <_EmccIncludePaths Include="$(_WasmIntermediateOutputPath.TrimEnd('\/'))" /> <_EmccIncludePaths Include="$(_WasmRuntimePackIncludeDir)mono-2.0" /> @@ -524,7 +527,7 @@ - + diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 2df2cf3dde077e..b324a4da7d2659 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -66,7 +66,7 @@ Defaults to false. - $(WasmAotProfilePath) - Path to an AOT profile file. - $(WasmExceptionHandling) - Enable support for the WASM Exception Handling feature. - - $(WasmSIMD) - Enable support for the WASM SIMD feature. + - $(WasmEnableSIMD) - Enable support for the WASM SIMD feature. Public items: - @(WasmExtraFilesToDeploy) - Files to copy to $(WasmAppDir). @@ -87,7 +87,7 @@ false false - false + false diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs index 659075cc69d9d7..d64c9739315100 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs @@ -137,6 +137,7 @@ protected string RunAndTestWasmApp(BuildArgs buildArgs, Dictionary? envVars = null, string targetFramework = DefaultTargetFramework, string? extraXHarnessMonoArgs = null, + string? extraXHarnessArgs = null, string jsRelativePath = "test-main.js") { buildDir ??= _projectDir; @@ -159,13 +160,15 @@ protected string RunAndTestWasmApp(BuildArgs buildArgs, throw new InvalidOperationException("Running tests with V8 on windows isn't supported"); // Use wasm-console.log to get the xharness output for non-browser cases - (string testCommand, string extraXHarnessArgs, bool useWasmConsoleOutput) = host switch + (string testCommand, string xharnessArgs, bool useWasmConsoleOutput) = host switch { RunHost.V8 => ("wasm test", $"--js-file={jsRelativePath} --engine=V8 -v trace", true), RunHost.NodeJS => ("wasm test", $"--js-file={jsRelativePath} --engine=NodeJS -v trace", true), _ => ("wasm test-browser", $"-v trace -b {host} --web-server-use-cop", false) }; + extraXHarnessArgs += " " + xharnessArgs; + string testLogPath = Path.Combine(_logPath, host.ToString()); string output = RunWithXHarness( testCommand, diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmSIMDTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmSIMDTests.cs index 8c5c397b82c3d0..26aa0a7e62ce43 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmSIMDTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmSIMDTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.IO; using Xunit; using Xunit.Abstractions; @@ -16,25 +17,114 @@ public WasmSIMDTests(ITestOutputHelper output, SharedBuildPerTestClassFixture bu } [Theory] - [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true, RunHost.All })] - public void BuildWithSIMD(BuildArgs buildArgs, RunHost host, string id) - => TestMain("main_simd_aot", - @" - using System; - using System.Runtime.Intrinsics; - - public class TestClass { - public static int Main() - { - var v1 = Vector128.Create(0x12345678); - var v2 = Vector128.Create(0x23456789); - var v3 = v1*v2; - Console.WriteLine(v3); - Console.WriteLine(""Hello, World!""); - - return 42; - } - }", - buildArgs, host, id, extraProperties: "true"); + [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ false, RunHost.All })] + public void BuildWithSIMD_NoAOT_ShouldRelink(BuildArgs buildArgs, RunHost host, string id) + { + string projectName = $"sim_with_workload_no_aot"; + buildArgs = buildArgs with { ProjectName = projectName }; + buildArgs = ExpandBuildArgs(buildArgs, "true"); + + (_, string output) = BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_simdProgramText), + Publish: false, + DotnetWasmFromRuntimePack: false)); + + if (!_buildContext.TryGetBuildFor(buildArgs, out _)) + { + // Check if this is not a cached build + Assert.Contains("Compiling native assets with excc", output); + } + + RunAndTestWasmApp(buildArgs, + extraXHarnessArgs: host == RunHost.NodeJS ? "--engine-arg=--experimental-wasm-simd" : "", + expectedExitCode: 42, + test: output => + { + Assert.Contains("<-2094756296, -2094756296, -2094756296, -2094756296>", output); + Assert.Contains("Hello, World!", output); + }, host: host, id: id); + } + + [Theory] + // https://github.com/dotnet/runtime/issues/75044 - disabled for V8, and NodeJS + //[MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true, RunHost.All })] + [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true, RunHost.Chrome })] + [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ false, RunHost.All })] + public void PublishWithSIMD_AOT(BuildArgs buildArgs, RunHost host, string id) + { + string projectName = $"sim_with_workload_aot"; + buildArgs = buildArgs with { ProjectName = projectName }; + buildArgs = ExpandBuildArgs(buildArgs, "true"); + + BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_simdProgramText), + DotnetWasmFromRuntimePack: false)); + + RunAndTestWasmApp(buildArgs, + extraXHarnessArgs: host == RunHost.NodeJS ? "--engine-arg=--experimental-wasm-simd" : "", + expectedExitCode: 42, + test: output => + { + Assert.Contains("<-2094756296, -2094756296, -2094756296, -2094756296>", output); + Assert.Contains("Hello, World!", output); + }, host: host, id: id); + } + + [Theory, TestCategory("no-workload")] + [InlineData("Debug", /*aot*/true, /*publish*/true)] + [InlineData("Debug", /*aot*/false, /*publish*/false)] + [InlineData("Debug", /*aot*/false, /*publish*/true)] + [InlineData("Release", /*aot*/true, /*publish*/true)] + [InlineData("Release", /*aot*/false, /*publish*/false)] + [InlineData("Release", /*aot*/false, /*publish*/true)] + public void BuildWithSIMDNeedsWorkload(string config, bool aot, bool publish) + { + string id = Path.GetRandomFileName(); + string projectName = $"simd_no_workload_{config}_aot_{aot}"; + BuildArgs buildArgs = new + ( + ProjectName: projectName, + Config: config, + AOT: aot, + ProjectFileContents: "placeholder", + ExtraBuildArgs: string.Empty + ); + + string extraProperties = """ + browser-wasm + true + """; + buildArgs = ExpandBuildArgs(buildArgs, extraProperties); + + (_, string output) = BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_simdProgramText), + Publish: publish, + ExpectSuccess: false, + UseCache: false)); + Assert.Contains("following workloads must be installed: wasm-tools", output); + } + + private static string s_simdProgramText = @" + using System; + using System.Runtime.Intrinsics; + + public class TestClass { + public static int Main() + { + var v1 = Vector128.Create(0x12345678); + var v2 = Vector128.Create(0x23456789); + var v3 = v1*v2; + Console.WriteLine(v3); + Console.WriteLine(""Hello, World!""); + + return 42; + } + }"; } }