Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wasm][mt] Fix System.Threading.Tasks.Parallel build #97505

Merged
merged 6 commits into from
Jan 26, 2024

Conversation

radekdoulik
Copy link
Member

@radekdoulik radekdoulik commented Jan 25, 2024

Fixes #91541
Fixes #91579
Fixes #91581
Fixes #91582
Fixes #91583
Fixes #97396
Fixes #97440

@@ -7,7 +7,7 @@
</PropertyGroup>
<PropertyGroup>
<TargetPlatformIdentifier>$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))</TargetPlatformIdentifier>
<FeatureWasmThreads Condition="'$(TargetPlatformIdentifier)' == 'browser' and '$(MonoWasmBuildVariant)' == 'multithread'">true</FeatureWasmThreads>
<FeatureWasmThreads Condition="'$(TargetOS)' == 'browser' and '$(MonoWasmBuildVariant)' == 'multithread'">true</FeatureWasmThreads>
Copy link
Member

@ilonatommy ilonatommy Jan 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the old thing, TargetPlatformIdentifier? Was it empty? I found:

4. Set the `TargetPlatformIdentifier` property in the project to be able to condition on it in properties in the project file.
, that it might be empty if it's not set explicitly

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not do it consistently in all project files if TargetPlatformIdentifier doesn't work well ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is the platform identifier from $(TargetFramework). I think it would have the value 'browser' if the target framework was something like net9.0-browser

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's interesting. TargetFramework is not in the form of net9.0-browser. We have quite a few places where we use the same condition, not connected with threading. It should mean that they are not triggered, e.g.

<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'unix' or '$(TargetPlatformIdentifier)' == 'browser' ">

<EmitCompilerGeneratedFiles Condition="'$(Configuration)' == 'Debug' and '$(TargetPlatformIdentifier)' == 'browser'">true</EmitCompilerGeneratedFiles>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@radekdoulik i didn't understand why/how you resolved this. We have many same conditions in the other project files. Do they all work or not ? Could we have them consistent ?

Copy link
Member

@akoeplinger akoeplinger Jan 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discourage using TargetOS to vary builds (except in some special cases for tests) because it defaults to the host OS if a target OS is not explicitly passed in, which is the case if you build a library from VS or in the "allConfiguration" CI build.

The correct solution here is to add $(NetCoreAppCurrent)-browser TFM and use TargetPlatformIdentifier in the condition.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@akoeplinger, @lewing I am curious, how are the produced assemblies used further in the process. So in this case, where does the assembly built with net9.0 TFM ends up and where the net9.0-browser one. I imagine they end up in the right Sdk and workload so that users projects get the right assembly?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see many <IgnoreForCI Condition="'$(TargetOS)' == 'browser'">true</IgnoreForCI> but I don't know what IgnoreForCI does.

There are also many <DebuggerSupport Condition="'$(DebuggerSupport)' == '' and '$(TargetOS)' == 'browser'">true</DebuggerSupport>

Overall we have '$(TargetOS)' != 'browser' 15x and '$(TargetOS)' == 'browser' 126x

Should we fix it all ?

Copy link
Member

@akoeplinger akoeplinger Jan 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in this case, where does the assembly built with net9.0 TFM ends up and where the net9.0-browser one. I imagine they end up in the right Sdk and workload so that users projects get the right assembly?

Yes the build system will select the right assets when building a specific runtime pack, based on the RID fallback graph in PortableRuntimeIdentifierGraph.json

[..] but I don't know what IgnoreForCI does.

IgnoreForCI skips sending a test project to helix, it is just an optimization for projects where all tests are disabled/skipped for whatever reason so that we don't waste resources sending and running a helix workitem where 0 tests are executed.

In theory the correct way would be to add additional browser TFMs here too but it'd make build times longer and test projects are always built for a specific target OS so we let it slide. The important part is that we only do this in tests, not in the src csproj. I've checked and only System.Linq.Parallel.csproj is affected (#97539 has the fix).

Copy link
Member

@akoeplinger akoeplinger Jan 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And just to be clear: the current way "works" because in CI/official builds we'll always have TargetOS=browser, the correct way is mostly important for VS scenarios e.g. you should be able to use the TFM dropdown in VS to select a different config and hit build to build the "browser' version, this likely won't work today anyway because of additional properties like MonoWasmBuildVariant.

@pavelsavara
Copy link
Member

/azp run runtime-wasm

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@pavelsavara
Copy link
Member

note that you need to look into AzDO runtime-wasm for the MT libraries leg, because it doesn't report failures on the github.

I will change it soon, see

@pavelsavara pavelsavara added arch-wasm WebAssembly architecture os-browser Browser variant of arch-wasm labels Jan 25, 2024
@ghost
Copy link

ghost commented Jan 25, 2024

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

Issue Details

Fixes #91541, #91581, #91582, #91583 and #91579

Author: radekdoulik
Assignees: radekdoulik
Labels:

arch-wasm, area-VM-threading-mono, os-browser

Milestone: -

@pavelsavara
Copy link
Member

image

Orange means something is broken.

System.Runtime.InteropServices.JavaScript.Tests I'm working on in #97441 and it's unrelated to you

System.Numerics.Tensors.Tests and System.Numerics.Tensors.Net8.Tests are broken by #97295 unrelated to you

System.Threading.Tasks.Extensions.Tests is #96545

@radekdoulik
Copy link
Member Author

Orange means something is broken.

System.Runtime.InteropServices.JavaScript.Tests I'm working on in #97441 and it's unrelated to you

System.Numerics.Tensors.Tests and System.Numerics.Tensors.Net8.Tests are broken by #97295 unrelated to you

System.Threading.Tasks.Extensions.Tests is #96545

these are unrelated, right, so it should be fine to merge it?

Copy link
Member

@pavelsavara pavelsavara left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix all the other projects which could have the same problem before you merge this.

@radekdoulik
Copy link
Member Author

/azp run runtime-wasm

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@radekdoulik
Copy link
Member Author

Please fix all the other projects which could have the same problem before you merge this.

There are few more places to fix. I will do it in a following PR as it might need more work in case there are build issues.

> git grep FeatureWasmThreads .|grep TargetPlatformIdentifier|cut -f1 -d:|while read proj; do echo --- $proj ---; grep \<TargetFramework $proj; done
--- src/libraries/System.Net.Http/src/System.Net.Http.csproj ---
    <TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-linux;$(NetCoreAppCurrent)-osx;$(NetCoreAppCurrent)-freebsd;$(NetCoreAppCurrent)-maccatalyst;$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent)-browser;$(NetCoreAppCurrent)-wasi;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-solaris;$(NetCoreAppCurrent)-haiku;$(NetCoreAppCurrent)-android;$(NetCoreAppCurrent)</TargetFrameworks>
--- src/libraries/System.Net.WebSockets.Client/src/System.Net.WebSockets.Client.csproj ---
    <TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppCurrent)-browser</TargetFrameworks>
--- src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj ---
    <TargetFrameworks>$(NetCoreAppCurrent)-browser;$(NetCoreAppCurrent)</TargetFrameworks>
--- src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj ---
    <TargetFrameworks>$(NetCoreAppCurrent)-browser;$(NetCoreAppCurrent)</TargetFrameworks>
--- src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj ---
    <TargetFrameworks>$(NetCoreAppCurrent)-browser;$(NetCoreAppCurrent)</TargetFrameworks>
--- src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj ---
    <TargetFrameworks>$(NetCoreAppCurrent)-browser</TargetFrameworks>
--- src/libraries/System.Threading.Tasks.Parallel/src/System.Threading.Tasks.Parallel.csproj ---
    <TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
--- src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj ---
    <TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
--- src/libraries/System.Threading/ref/System.Threading.csproj ---
    <TargetFramework>$(NetCoreAppCurrent)</TargetFramework>

I was thinking about adding the logic to the src/libraries/Directory.Build.props. That would probably not work though as it is imported too early. But maybe we could try to add a new target to the Directory.Build.targets to run before Build or Csc target to set the define we need. I will play with it later.

@radekdoulik
Copy link
Member Author

/azp run runtime-wasm

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@radekdoulik
Copy link
Member Author

/azp run runtime-wasm

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@radekdoulik radekdoulik merged commit c105e7d into dotnet:main Jan 26, 2024
130 of 137 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Feb 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.