dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.97k stars 4.66k forks source link

[wasm] Add test checking that disabiling SIMD actually disables it #89302

Open radekdoulik opened 1 year ago

radekdoulik commented 1 year ago

The SIMD cannot be disabled anymore. These are the 2 parts we need to fix:

optionally:

following step:

radekdoulik commented 1 year ago

@kg do we need add_compile_options(-msimd128) in the src/mono/CMakeLists.txt for the interpreter to work with SIMD? if not, we can probably remove it. I think the performance will not be affected much by this. Otherwise we would need multiple versions of mono native libs I think.

vargaz commented 1 year ago

I think --enable-simd is needed by wasm-opt to be able to read an input file which uses simd opcodes.

kg commented 1 year ago

@kg do we need add_compile_options(-msimd128) in the src/mono/CMakeLists.txt for the interpreter to work with SIMD? if not, we can probably remove it. I think the performance will not be affected much by this. Otherwise we would need multiple versions of mono native libs I think.

Without -msimd128 no code that uses wasm intrinsics will compile, even if we don't run it. So we would need to ifdef everything relevant out I think.

Part of the problem is that -msimd128 isn't just an 'enable support' flag, unfortunately it turns a bunch of other stuff on by default and that's probably the source of the sections or opcodes that are breaking things for people.

I don't think the switch specifically needs to be there; I tried a bunch of things to try and get SIMD to work and that was the only simple solution I found that worked.

ghost commented 1 year ago

Tagging subscribers to 'arch-wasm': @lewing See info in area-owners.md if you want to be subscribed.

Issue Details
The SIMD cannot be disabled anymore. These are the 2 parts we need to fix: - [ ] do not put `-msimd128` to `emcc-default.rsp`, otherwise we compile with SIMD even when `WasmEnableSIMD` is `false`. Instead add it conditionally in `src/mono/wasm/wasm.proj`, `src/mono/wasm/runtime/CMakeLists.txt` and `src/mono/wasm/build/WasmApp.Native.targets` - [ ] do not build our mono runtime with `-msimd128` or provide multiple native libraries versions optionally: - [ ] do not pass '--enable-simd' to `wasm-opt`. I think this doesn't add any SIMD instructions, so we probably don't need it. We should check it though. following step: - [ ] add WBT test to check that build with SIMD disabled produces `.wasm` files without SIMD instructions. This can be done easily once we have the `wa-info` tool in the runtime repo.
Author: radekdoulik
Assignees: radekdoulik
Labels: `arch-wasm`, `area-Build-mono`
Milestone: 8.0.0
radekdoulik commented 1 year ago

For mono libs and src/mono/CMakeLists.txt I will try to extract the interp simd code to a separate library, similar to what we do for exception handling, and link it conditionally.

radekdoulik commented 1 year ago

remaining parts can be done in net9

KubaGluszkiewicz commented 1 year ago

Hello, since our browser wasm application is deployed into various TV Systems like Tizen or WebOS which are internally baked by older chromium versions, disabling SIMD support is crucial for us. I'm trying to follow issues here (at least 2 were open related to enabling SIMD by default), and i see you are trying to fix it. I'm using version .net8 preview 7 and i'm not able to switch off SIMD support using csproj settings. Question is it possible in Preview7 to fully disable SIMD? If not, it will be possible in upcoming RC1 version?

My project settings:

<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<WasmEnableExceptionHandling>False</WasmEnableExceptionHandling>
<WasmEnableSIMD>False</WasmEnableSIMD>
<WasmBuildNative>True</WasmBuildNative>

At program launch i'm getting bunch of errors like this:

MONO_WASM: instantiate_wasm_module() failed CompileError: WebAssembly.instantiateStreaming(): Compiling function #104:"19" failed: Invalid opcode (enable with --experimental-wasm-simd) @+28002
nt @ dotnet.runtime.js:3
dotnet.js:3 MONO_WASM: CompileError: WebAssembly.instantiateStreaming(): Compiling function #104:"19" failed: Invalid opcode (enable with --experimental-wasm-simd) @+28002
l @ dotnet.js:3
main.js:26 Error initializing dotnet: CompileError: WebAssembly.instantiateStreaming(): Compiling function #104:"19" failed: Invalid opcode (enable with --experimental-wasm-simd) @+28002
(anonymous) @ main.js:26
dotnet.js:3 Error in mono_download_assets: CompileError: WebAssembly.instantiateStreaming(): Compiling function #104:"19" failed: Invalid opcode (enable with --experimental-wasm-simd) @+28002
(anonymous) @ dotnet.js:3
4dotnet.js:3 Uncaught (in promise) CompileError: WebAssembly.instantiateStreaming(): Compiling function #104:"19" failed: Invalid opcode (enable with --experimental-wasm-simd) @+28002
dotnet.runtime.js:3 Uncaught (in promise) CompileError: WebAssembly.instantiateStreaming(): Compiling function #104:"19" failed: Invalid opcode (enable with --experimental-wasm-simd) @+28002
2index.html:1 Uncaught (in promise) CompileError: WebAssembly.instantiateStreaming(): Compiling function #104:"19" failed: Invalid opcode (enable with --experimental-wasm-simd) @+28002

not sure what i can do more to get rid of SIMD support in .Net8

maraf commented 1 year ago

@KubaGluszkiewicz Just a note, use lower case true/false in MSBuild properties.

lewing commented 11 months ago

<WasmEnableSIMD>false</WasmEnableSIMD> should be the only thing required to disable simd (and eh since it defaults to the simd setting) and the setting is fully functional now.

maraf commented 11 months ago

<WasmEnableSIMD>false</WasmEnableSIMD> should be the only thing required to disable simd (and eh since it defaults to the simd setting) and the setting is fully functional now.

I have it on my list. Using chrome 85 on CI should be enough

lewing commented 10 months ago

add WBT test to check that build with SIMD disabled produces .wasm files without SIMD instructions. This can be done easily once we have the wa-info tool in the runtime repo.

Running wasm-opt without --enable- is an easy way to see what is in use

paulguz-datapa commented 8 months ago

We have customers hitting this on Windows 10 machines. What is the timescale for the fix?

maraf commented 8 months ago

@paulguz-datapa Disabling SIMD should be working, they this issue open only to make an automated test. Are you setting both WasmEnableExceptionHandling and WasmEnableSIMD to false? I have published a simple with disabled SIMD here https://maraf.github.io/dotnet-wasm-nosimd/. Can you check it works in your environment?

paulguz-datapa commented 8 months ago

@maraf Yes, those flags work, thanks.

lewing commented 7 months ago

Closing as completed if this is incorrect please reopen

luccawilli commented 7 months ago

@maraf unfortunately your fix does not fix our problem. We got a small project running on blazor webassemly and after the update to .net8, we received feedback that the website was no longer working for them. As mentioned in this Issue, we decided to disable SIMD (the error message also pointed it out) via adding the Wasm Section to our project file.

<WasmEnableSIMD>false</WasmEnableSIMD>
<WasmEnableExceptionHandling>false</WasmEnableExceptionHandling>

Unfortunately, this does not solve the actual problem. We received still the same error. grafik

Our test environment runs on "Microsoft Windows Server 2019 Standard - 10.0.17763" is a Virtual Machine with the processor "Intel64 Family 6 Model 85 Stepping 7 GenuineIntel" (Unfortunately without SIMD support). Hosting seems to be unrelated, I get the error in the IIS as well as in the Docker Image hosted Variant.

Unfortunately, I am not allowed to share the project code with you, so I have created a sample application that at least also outputs a SIMD error message. Unfortunately I can't get the same error as in the project above. https://github.com/luccawilli/dotnet-wasm-nosimd

grafik

It works on my personal machine ;) grafik

Nevertheless, I suspect that SIMD is still included in the published Version somewhere. Do you have an idea what could go wrong?

maraf commented 7 months ago

@luccawilli If I understand it correctly, you are able to reproduce the error in your test environment, right? Can we please verify that https://maraf.github.io/dotnet-wasm-nosimd/ works on the machine without SIMD?

luccawilli commented 7 months ago

@maraf correct, your example works without an error. But it does not use any Pages or Components.

maraf commented 7 months ago

But it does not use any Pages or Components.

It's plain WebAssembly without blazor.

And your sample with Blazor doesn't work https://github.com/luccawilli/dotnet-wasm-nosimd, right? Do you have wasm-tools workload installed? (dotnet workload install wasm-tools)

luccawilli commented 7 months ago

@maraf Yes correct, mine does not work. And yes i installed wasm-tools.

maraf commented 7 months ago

Thanks! I'm getting the same "AllowRange" error on my machine. I'll investigate it

LostBeard commented 7 months ago

I have created demonstration projects showing how to build Blazor WASM apps with both SIMD enabled and disabled. And then loading the appropriate build at runtime based on the environment.

Blazor Web App SIMD Detect Example
BlazorWebAppSIMDDetectExample

Blazor WebAssembly Standalone SIMD Detect Example BlazorWASMSIMDDetectExample

maraf commented 7 months ago

@luccawilli The "AllowRange" error comes from the Jiterpreter that is testing what capabilities it can use. We'll prepare a fix for it not to test SIMD on runtime when it was disabled during compilation.

Anyway, with disable SIMD during build (WasmEnableSIMD=false and WasmEnableExceptionHandling=false) the app works despite it prints error to the console (the Blazor UI renders and all interactions work). You can get rid of the error with the following setting

<BlazorWebAssemblyRuntimeOptions>--no-jiterpreter-simd-enabled --no-jiterpreter-wasm-eh-enabled</BlazorWebAssemblyRuntimeOptions>
LostBeard commented 7 months ago

My comment here

Interesting note. I have noticed that my devices or browsers that do not support SIMD also throw an error MONO_WASM: Disabling jiterpreter after 2 failures if BlazorWebAssemblyJiterpreter is not also disabled. (The app still runs with the error.) Disabling both SIMD and the jiterpreter when SIMD is not supported works without any further issues on my test devices.

I found that disabling SIMD without also disabling BlazorWebAssemblyJiterpreter gave an error but still allowed the app to run.

@maraf You "cc@kg" my above comment on that thread. maraf quoting my above comment

maraf commented 7 months ago

I found that disabling SIMD without also disabling BlazorWebAssemblyJiterpreter gave an error but still allowed the app to run.

You actually don't need to disable the whole jiterpreter, just the SIMD and EH

luccawilli commented 7 months ago

@maraf Thank you for the investigation. As i see the error in my test app has vanished :)

Unfortunately, the change does not yet solve any problems in our main project. I will try to improve my test app, so that i can show you my main problem.

luccawilli commented 7 months ago

So I have improved my example. It now shows the same error that we get in our main project. https://github.com/luccawilli/dotnet-wasm-nosimd-try2

I also added the publish result and the folder publish profile.

The error shown in my test system: grafik

No errors on my system (with SIMD support) (except for the missing icon) grafik

@maraf Can you also investigate this one? Thanks alot :)

maraf commented 7 months ago

Why are you setting WasmBuildNative=false? This setting disables relinking .NET runtime and thus makes all the other settings void. We are improving the experience in 9 to produce an error when incompatible settings are used

luccawilli commented 7 months ago

Oh damn, okay alright. I didn't know that. I had to add it because my build agent (a linux machine) had thrown the following error: WasmApp.Native.targets(737,5): error : MarshalingPInvokeScanner.Assemblies cannot be empty

But I think I can ignore that, since it only needs to be published in my Docker-Image. Btw. to build and publish it in a Docker-Image, i had to install python3. (Maybe that also a problem on my build agent.) RUN apt-get update RUN apt-get install -y python3

Thank you once again Best regards