You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds a CoreCLR browser-WASM composite ReadyToRun microbenchmark lane next to the per-assembly R2R lane from #5297.
Dependencies
[wasm][coreclr] Enable composite ReadyToRun publishing runtime#134618 ([wasm][coreclr] Enable composite ReadyToRun publishing): merged Oct 1. The lane needs a perf-build BrowserWasmCoreCLR artifact from a runtime commit that includes it; with an older artifact it fails with the runtime's PublishReadyToRunComposite is not supported for CoreCLR browser-wasm error.
CLI (micro_benchmarks.py): new --wasm-ready-to-run-composite option that implies R2R. --wasm-ready-to-run still means per-assembly. Both options require --wasm --wasm-runtime-flavor CoreCLR. configure_wasm_ready_to_run always writes both PERFLAB_WASM_READY_TO_RUN and PERFLAB_WASM_READY_TO_RUN_COMPOSITE, so a stale parent value can't select the wrong mode. benchmarks_ci.py accepts --wasm-workload-source with either mode.
Job script (run_performance_job.py): r2r_run_type == "r2r_composite" maps to R2RType=r2r_composite and passes --wasm-ready-to-run-composite to the Helix work item. The workload-source SDK cohort applies to both R2R modes. r2r_composite is rejected for any runtime type other than wasm_coreclr.
MSBuild (MicroBenchmarks.Wasm.targets):
PublishReadyToRunComposite now comes from the selected mode. PublishTrimmed, WebCIL and ContainerFormat=wasm are the same as before, so per-assembly mode is unchanged.
ValidateWasmReadyToRunConfiguration checks that the applied composite value matches the selected mode, and that composite mode is only used together with R2R.
ValidateWasmReadyToRunOutputs (after _CreateR2RImages), composite mode: requires exactly one _ReadyToRunCompileList item with CreateCompositeImage=true. Its OutputR2RImage must end in .r2r.wasm and exist on disk, and there must be at least one _ReadyToRunCompositeBuildInput or _ReadyToRunCompositeUnrootedBuildInput.
ValidateWasmReadyToRunOutputs, per-assembly mode: now also fails if a composite image was planned.
New ValidateWasmReadyToRunCompositePublishAssets (after ProcessPublishFilesForWasm): requires exactly one _WasmCompositePublishStaticWebAsset with AssetTraitValue=readyToRunComposite. GenerateWasmBootJson routes exactly that asset to resources.coreAssembly (with isCompositeImage). This catches a composite that was compiled but never shipped or loaded.
I ran every guard branch locally in a stub MSBuild harness: each failure path reported its error, and the valid composite and per-assembly paths passed.
Crossgen2Tasks shim (temporary): build_wasm_coreclr_payload copies staging/Crossgen2Tasks/ into the Helix payload as crossgen2-tasks/ when the artifact has it (and fails on an incomplete copy). For the r2r_composite lane only, run_performance_job.py exports PERFLAB_WASM_CROSSGEN2_TASKS_DIR in the Helix pre-commands, and micro_benchmarks.py turns that into Crossgen2SdkOverridePropsPath/Crossgen2SdkOverrideTargetsPath environment properties in composite mode. They must be environment properties, not set in MicroBenchmarks.Wasm.targets, because the WebAssembly SDK reads them during props evaluation, before BenchmarkDotNet imports that file. Per-assembly R2R keeps the SDK's own tasks. If the artifact has no shim, the job logs a warning and the composite build uses the SDK's tasks.
Pipeline: new coreclr_r2r_composite_v8 job in runtime-wasm-perf-jobs.yml. It is identical to coreclr_r2r_v8 except r2rRunType: 'r2r_composite': same release-branch exclusion, payload, machine and engine. The run-performance-job.yml workload-source condition now covers both R2R types.
Tests and docs: test_wasm_coreclr_r2r.py covers mode parsing and validation, env configuration (including stale values), work item forwarding, run configuration, the MSBuild property and guard structure, and a check that the new pipeline lane matches the per-assembly lane apart from its identity. They also cover shim staging in the payload, the pre-command export, and that the override applies to composite mode only. The docs describe the new option and the shim variable.
Composite runs report R2RType=r2r_composite, so PerfLab keeps them in a separate history from per-assembly R2RType=r2r and from the interpreted coreclr_v8 lane. Existing histories don't change.
Risks to watch in the first validation run
Crossgen2 time/memory vs. --buildTimeout 1200: one composite covers the whole trimmed benchmark closure, including Roslyn (Microsoft.CodeAnalysis*). It is one large, serial compile rather than many small ones, and could exceed the BDN build timeout or the machine's memory.
BDN's WASM launcher and coreAssembly: the composite owner is loaded from the boot config's resources.coreAssembly before CoreCLR initializes, with component stubs staying in the TPA. BDN's generated WASM host must use the SDK's boot config and loader unchanged. If it doesn't, stubs will fail-fast because they can't find the owner.
ColdStart/instantiation cost: instantiating one large .wasm image may noticeably move first-iteration and startup-sensitive numbers compared with per-assembly R2R.
Shim compatibility: Crossgen2Tasks.dll is built against the same runtime global.json SDK that the artifact ships as dotnet-none, so it should load into that SDK's MSBuild. A mismatch would show up as a task-load error at the start of the composite compile.
Notes (no changes made)
PublishReadyToRunExclude: none remain in MicroBenchmarks.csproj; Enable Jil for CoreCLR WASM R2R #5317, which removed the Jil exclusion, is already in main. Any future exclusion would keep that assembly out of the composite (it would stay IL/interpreted), which is the expected composite behavior.
_AOT_InternalForceInterpretAssemblies (Roslyn): this is a Mono AOT item and has no effect on CoreCLR Crossgen2. In composite mode, Roslyn is compiled into the composite, the main contributor to the compile-time risk above. If that turns out too slow, a follow-up could exclude Microsoft.CodeAnalysis* from the composite.
Note
This PR description was generated with GitHub Copilot assistance.
Add a coreclr_r2r_composite_v8 job (r2rRunType r2r_composite) alongside
the per-assembly coreclr_r2r_v8 lane. The mode flows through
run_performance_job.py (R2RType=r2r_composite, a separate PerfLab
history) to a new --wasm-ready-to-run-composite micro_benchmarks option,
which sets PERFLAB_WASM_READY_TO_RUN_COMPOSITE for MSBuild.
MicroBenchmarks.Wasm.targets now sets PublishReadyToRunComposite from
the selected mode, validates it, and in composite mode verifies that
exactly one <entry>.r2r.wasm composite image was produced with
component inputs and that it was defined as the readyToRunComposite
publish asset that GenerateWasmBootJson routes to coreAssembly.
Depends on dotnet/runtime#134618.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Composite CoreCLR WASM R2R needs ReadyToRun SDK tasks that name the
owner image <entry>.r2r.wasm (dotnet/sdk#56395), which the SDK shipped
in the BrowserWasmCoreCLR perf artifact does not have yet.
dotnet/runtime#135204 stages runtime's wasm-aware Crossgen2Tasks shim
into that artifact as staging/Crossgen2Tasks.
Copy the shim into the Helix payload when present, export its location
as PERFLAB_WASM_CROSSGEN2_TASKS_DIR for the r2r_composite lane only, and
in composite mode pass it to the WebAssembly SDK through
Crossgen2SdkOverridePropsPath/Crossgen2SdkOverrideTargetsPath. These must
be environment properties because the SDK reads them during props
evaluation. Per-assembly R2R keeps the SDK's own ReadyToRun tasks.
TODO: remove once the SDK carries dotnet/sdk#56395
(dotnet/runtime#135023).
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
configure_wasm_crossgen2_sdk_override now removes inherited
Crossgen2SdkOverridePropsPath/Crossgen2SdkOverrideTargetsPath before
deciding whether to apply the shim, so per-assembly R2R always keeps
the SDK's ReadyToRun tasks and a composite run without a staged shim
cannot pick up a stale path. PERFLAB_WASM_CROSSGEN2_TASKS_DIR remains
the only way to select a shim.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Raise an error for incomplete Crossgen2Tasks shims
scripts/build_runtime_payload.py:361
When the artifact is supplied as a directory and staging/Crossgen2Tasks exists but contains none of the required files (or only unrelated files), this branch treats the malformed shim as an old artifact and silently falls back to the SDK tasks. That contradicts the intended fail-fast behavior for an incomplete copy and makes the composite lane proceed with tasks that will fail the runtime's owner-name validation; distinguish an absent shim directory from a present-but-incomplete one and raise ValueError for the latter.
…ifact (#135204)
The new composite R2R microbenchmark lane in dotnet/performance#5324
(`coreclr_r2r_composite_v8`) publishes CoreCLR browser-wasm with
`PublishReadyToRunComposite`. #134618's
`_WasmCoreClrValidateCompositeTasks` rejects that publish unless the SDK
ReadyToRun tasks name the owner `<entry>.r2r.wasm`. The SDK tasks only
learn to do that in dotnet/sdk#56395, which hasn't reached runtime's
global.json SDK yet (11.0.100-rc.1.26420.103).
This PR copies the in-tree wasm-aware task shim, the same one
Wasm.Build.Tests use via
`Crossgen2SdkOverridePropsPath`/`Crossgen2SdkOverrideTargetsPath`, into
the `BrowserWasmCoreCLR` perf artifact. The shim comes from
`artifacts/bin/Crossgen2Tasks/<config>/`, which `Build.proj` already
produces.
Staged layout (flat, no config subfolder; this is the path
dotnet/performance consumes):
```
staging/Crossgen2Tasks/Crossgen2Tasks.dll
staging/Crossgen2Tasks/Microsoft.NET.CrossGen.props
staging/Crossgen2Tasks/Microsoft.NET.CrossGen.targets
```
The step fails if the source directory or any of these three files is
missing. Only the CoreCLR leg (`includeCoreClrToolchainPacks: true`)
changes; the Mono artifact is untouched.
This is temporary: remove it once dotnet/sdk#56395 reaches global.json.
Tracked by #135023.
Validation: YAML parses (`python3 yaml.safe_load`) and `git diff
--check` is clean. The pipeline itself hasn't run yet.
> [!NOTE]
> This PR was generated with the help of GitHub Copilot.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a287cfc0-a881-4272-9024-bdaf9d9db4ef
A BrowserWasmCoreCLR directory artifact with a staging/Crossgen2Tasks
folder that lacks the required files was treated like an artifact
without the shim, silently falling back to the SDK ReadyToRun tasks.
Only a missing folder (directory artifacts) or no extracted entries
(archives) now means "no shim"; anything else must contain
Crossgen2Tasks.dll and Microsoft.NET.CrossGen.props/.targets or
build_wasm_coreclr_payload raises ValueError. Add archive coverage.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a CoreCLR browser-WASM composite ReadyToRun microbenchmark lane next to the per-assembly R2R lane from #5297.
Dependencies
[wasm][coreclr] Enable composite ReadyToRun publishing): merged Oct 1. The lane needs a perf-buildBrowserWasmCoreCLRartifact from a runtime commit that includes it; with an older artifact it fails with the runtime'sPublishReadyToRunComposite is not supported for CoreCLR browser-wasmerror._WasmCoreClrValidateCompositeTasksfails before the composite compile unless the SDK's ReadyToRun tasks name the owner<entry>.r2r.wasm. Port runtime PR dotnet/runtime#133111 R2R changes to SDK Crossgen tasks sdk#56395 merged on Oct 2 but hasn't reached the SDK in the perf artifact (dotnet-none, pinned by runtime'sglobal.jsonto 11.0.100-rc.1.26420.103). Until it does, this PR uses runtime'sCrossgen2Tasksshim, which [wasm][coreclr] Ship Crossgen2Tasks shim in the CoreCLR wasm perf artifact runtime#135204 stages into the artifact asstaging/Crossgen2Tasks/. Without that PR (or a newer SDK), the composite lane fails early with that clear error rather than producing bad numbers. The shim is temporary; removal is tracked by [wasm] Remove the in-repo Crossgen2Tasks shim for browser composite R2R once the SDK names wasm R2R outputs runtime#135023.Changes
micro_benchmarks.py): new--wasm-ready-to-run-compositeoption that implies R2R.--wasm-ready-to-runstill means per-assembly. Both options require--wasm --wasm-runtime-flavor CoreCLR.configure_wasm_ready_to_runalways writes bothPERFLAB_WASM_READY_TO_RUNandPERFLAB_WASM_READY_TO_RUN_COMPOSITE, so a stale parent value can't select the wrong mode.benchmarks_ci.pyaccepts--wasm-workload-sourcewith either mode.run_performance_job.py):r2r_run_type == "r2r_composite"maps toR2RType=r2r_compositeand passes--wasm-ready-to-run-compositeto the Helix work item. The workload-source SDK cohort applies to both R2R modes.r2r_compositeis rejected for any runtime type other thanwasm_coreclr.MicroBenchmarks.Wasm.targets):PublishReadyToRunCompositenow comes from the selected mode.PublishTrimmed, WebCIL andContainerFormat=wasmare the same as before, so per-assembly mode is unchanged.ValidateWasmReadyToRunConfigurationchecks that the applied composite value matches the selected mode, and that composite mode is only used together with R2R.ValidateWasmReadyToRunOutputs(after_CreateR2RImages), composite mode: requires exactly one_ReadyToRunCompileListitem withCreateCompositeImage=true. ItsOutputR2RImagemust end in.r2r.wasmand exist on disk, and there must be at least one_ReadyToRunCompositeBuildInputor_ReadyToRunCompositeUnrootedBuildInput.ValidateWasmReadyToRunOutputs, per-assembly mode: now also fails if a composite image was planned.ValidateWasmReadyToRunCompositePublishAssets(afterProcessPublishFilesForWasm): requires exactly one_WasmCompositePublishStaticWebAssetwithAssetTraitValue=readyToRunComposite.GenerateWasmBootJsonroutes exactly that asset toresources.coreAssembly(withisCompositeImage). This catches a composite that was compiled but never shipped or loaded.build_wasm_coreclr_payloadcopiesstaging/Crossgen2Tasks/into the Helix payload ascrossgen2-tasks/when the artifact has it (and fails on an incomplete copy). For ther2r_compositelane only,run_performance_job.pyexportsPERFLAB_WASM_CROSSGEN2_TASKS_DIRin the Helix pre-commands, andmicro_benchmarks.pyturns that intoCrossgen2SdkOverridePropsPath/Crossgen2SdkOverrideTargetsPathenvironment properties in composite mode. They must be environment properties, not set inMicroBenchmarks.Wasm.targets, because the WebAssembly SDK reads them during props evaluation, before BenchmarkDotNet imports that file. Per-assembly R2R keeps the SDK's own tasks. If the artifact has no shim, the job logs a warning and the composite build uses the SDK's tasks.coreclr_r2r_composite_v8job inruntime-wasm-perf-jobs.yml. It is identical tocoreclr_r2r_v8exceptr2rRunType: 'r2r_composite': same release-branch exclusion, payload, machine and engine. Therun-performance-job.ymlworkload-source condition now covers both R2R types.test_wasm_coreclr_r2r.pycovers mode parsing and validation, env configuration (including stale values), work item forwarding, run configuration, the MSBuild property and guard structure, and a check that the new pipeline lane matches the per-assembly lane apart from its identity. They also cover shim staging in the payload, the pre-command export, and that the override applies to composite mode only. The docs describe the new option and the shim variable.Validation
python3 -m pytest -q scripts/tests/test_wasm_coreclr_r2r.py scripts/tests/test_run_performance_job.py: 79 passed.git diff --check: clean.Results identity
Composite runs report
R2RType=r2r_composite, so PerfLab keeps them in a separate history from per-assemblyR2RType=r2rand from the interpretedcoreclr_v8lane. Existing histories don't change.Risks to watch in the first validation run
--buildTimeout 1200: one composite covers the whole trimmed benchmark closure, including Roslyn (Microsoft.CodeAnalysis*). It is one large, serial compile rather than many small ones, and could exceed the BDN build timeout or the machine's memory.coreAssembly: the composite owner is loaded from the boot config'sresources.coreAssemblybefore CoreCLR initializes, with component stubs staying in the TPA. BDN's generated WASM host must use the SDK's boot config and loader unchanged. If it doesn't, stubs will fail-fast because they can't find the owner..wasmimage may noticeably move first-iteration and startup-sensitive numbers compared with per-assembly R2R.Crossgen2Tasks.dllis built against the same runtimeglobal.jsonSDK that the artifact ships asdotnet-none, so it should load into that SDK's MSBuild. A mismatch would show up as a task-load error at the start of the composite compile.Notes (no changes made)
PublishReadyToRunExclude: none remain inMicroBenchmarks.csproj; Enable Jil for CoreCLR WASM R2R #5317, which removed the Jil exclusion, is already inmain. Any future exclusion would keep that assembly out of the composite (it would stay IL/interpreted), which is the expected composite behavior._AOT_InternalForceInterpretAssemblies(Roslyn): this is a Mono AOT item and has no effect on CoreCLR Crossgen2. In composite mode, Roslyn is compiled into the composite, the main contributor to the compile-time risk above. If that turns out too slow, a follow-up could excludeMicrosoft.CodeAnalysis*from the composite.Note
This PR description was generated with GitHub Copilot assistance.