[SDKv2] Migrate WinML EP downloads to WinML 2.x (reg-free runtime)#788
Open
bmehta001 wants to merge 31 commits into
Open
[SDKv2] Migrate WinML EP downloads to WinML 2.x (reg-free runtime)#788bmehta001 wants to merge 31 commits into
bmehta001 wants to merge 31 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
44fb8d1 to
ae5ad90
Compare
ae5ad90 to
c240a00
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR migrates the WinML EP download/discovery path from WinML 1.x (Windows App SDK bootstrap required) to WinML 2.x (Microsoft.Windows.AI.MachineLearning, reg-free runtime), and unifies ORT/GenAI pins across WinML and non-WinML flavors to simplify build + packaging across C++, C#, JS, Python, and CI.
Changes:
- Removes Windows App SDK bootstrap plumbing (
BootstrapadditionalSettings, bootstrap DLL staging, and native bootstrap helper) across all SDK bindings. - Switches WinML EP catalog acquisition to
Microsoft.Windows.AI.MachineLearning(NuGet + first-party CMake config) and updates packaging/staging to ship the reg-free runtime DLL where needed. - Unifies ORT/GenAI version pins (deletes WinML-specific deps JSON and removes WinML branching in CMake and the Python v2 build backend).
Reviewed changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| sdk_v2/python/test/integration/test_configuration_native.py | Updates integration test to stop using the removed Bootstrap additional setting. |
| sdk_v2/python/README.md | Removes WinML-only Bootstrap=false example from docs. |
| sdk_v2/python/pyproject.toml | Updates comments to reflect single deps JSON source for both wheel flavors. |
| sdk_v2/python/_build_backend/init.py | Drops WinML-specific deps JSON selection; always rewrites from deps_versions.json. |
| sdk_v2/js/test/bootstrap-autodetect.test.ts | Deletes tests for bootstrap auto-detect (no longer relevant with WinML 2.x reg-free runtime). |
| sdk_v2/js/src/foundryLocalManager.ts | Removes bootstrap auto-detect logic from manager initialization. |
| sdk_v2/js/script/copy-native.mjs | Stops copying Bootstrap.dll; now copies Microsoft.Windows.AI.MachineLearning.dll. |
| sdk_v2/deps_versions_winml.json | Removes WinML-specific ORT pin file (pins are unified). |
| sdk_v2/cs/src/Microsoft.AI.Foundry.Local.csproj | Lowers WinML package TFM to Windows 10 19H1-era baseline. |
| sdk_v2/cs/src/FoundryLocalManager.cs | Removes WinML bootstrap default injection into AdditionalSettings. |
| sdk_v2/cpp/test/sdk_api/ep_detection_test.cc | Updates WinML EP test comment to reflect Win10 19H1+ support. |
| sdk_v2/cpp/test/CMakeLists.txt | Increases gtest discovery timeout to accommodate WinML build startup costs. |
| sdk_v2/cpp/src/winml_bootstrap.h | Deletes WinAppSDK bootstrap helper header. |
| sdk_v2/cpp/src/winml_bootstrap.cc | Deletes WinAppSDK bootstrap helper implementation. |
| sdk_v2/cpp/src/manager.cc | Removes bootstrap lifecycle; enables WebGPU EP path for WinML builds now that ORT is unified. |
| sdk_v2/cpp/src/ep_detection/winml_ep_bootstrapper.cc | Removes OS-version gating; improves diagnostics when the WinML runtime DLL is absent. |
| sdk_v2/cpp/src/ep_detection/cuda_ep_bootstrapper.cc | Collapses CUDA EP download to a single ORT-aligned payload (no WinML branching). |
| sdk_v2/cpp/nuget/pack.py | Packages Microsoft.Windows.AI.MachineLearning.dll as the optional WinML sibling DLL. |
| sdk_v2/cpp/docs/MigrationPlan_20260410.md | Updates migration plan documentation for WinML 2.x acquisition and behavior. |
| sdk_v2/cpp/docs/EpDetectionPlan.md | Updates EP detection plan to WinML 2.x reg-free runtime and new package layout. |
| sdk_v2/cpp/docs/CppPortGuide.md | Updates port guide WinML requirements note to Win10 19H1+ reg-free runtime. |
| sdk_v2/cpp/CMakeLists.txt | Gates find_package(WinMLEpCatalog) behind FOUNDRY_LOCAL_USE_WINML; removes bootstrap linking/copy; ensures WinML DLL copy uses catalog DLL dir. |
| sdk_v2/cpp/cmake/FindWinMLEpCatalog.cmake | Switches acquisition to Microsoft.Windows.AI.MachineLearning and uses the package’s first-party CMake config to define targets and DLL dir. |
| sdk_v2/cpp/cmake/FindOnnxRuntimeGenAI.cmake | Removes WinML-vs-standard package branching; uses a single GenAI package. |
| sdk_v2/cpp/cmake/FindOnnxRuntime.cmake | Removes WinML-specific deps file selection; uses unified ORT pin. |
| sdk_v2/cpp/build.py | Updates --use_winml messaging and changes override define to WINML_EP_CATALOG_VERSION. |
| .pipelines/v2/templates/steps-prefetch-nuget.yml | Updates WinML prefetch to download the reg-free package directly (no transitive Foundation resolution). |
| .pipelines/v2/templates/steps-build-windows.yml | Updates native staging to include Microsoft.Windows.AI.MachineLearning.dll for WinML builds. |
| .pipelines/v2/templates/stages-sdk-v2.yml | Removes WinML-specific ORT version parameter wiring. |
| .pipelines/v2/templates/stages-build-native.yml | Unifies WinML and non-WinML builds on the same ORT version parameter. |
| .pipelines/v2/sdk_v2-pipeline-plan.md | Updates pipeline plan documentation for unified ORT pins and WinML 2.x package handling. |
| .pipelines/foundry-local-packaging.yml | Updates packaging pipeline variables to use WinML 2.x version and removes WinML-specific ORT version variable. |
Switch from `Microsoft.WindowsAppSDK.ML` 1.8.2192 (WinML 1.x, WinAppSDK
bootstrap required, Win11 24H2+) to `Microsoft.Windows.AI.MachineLearning`
2.1.6 (WinML 2.x, registration-free, Win10 19H1+). This brings Foundry-Local
in line with the same migration neutron-server completed.
Highlights:
* Remove WinAppSDK Bootstrap plumbing across all SDKs. The `Bootstrap`
`additionalSettings` key — which used to flip on WinAppSDK init in the
native layer — is gone in every binding (C++, C#, JS, Python). It was an
internal init knob; no public surface signaled it as a stable contract.
- C++: delete winml_bootstrap.{h,cc}, the WinAppSdkBootstrap link target,
the Bootstrap.dll post-build copy, and the additional_options key
handling in Manager::Create / Destroy.
- C#: drop the `IS_WINML` default that injected Bootstrap=true.
Lower TFM from net9.0-windows10.0.26100.0 to net9.0-windows10.0.18362.0.
- JS: delete applyBootstrapAutoDetect and its test; drop Bootstrap.dll
from copy-native script.
- Python: drop `Bootstrap=false` examples from README and integration
test.
* Unify ORT to 1.25.1 / OnnxRuntimeGenAI to 0.13.2 for both the WinML and
non-WinML flavors. Delete sdk_v2/deps_versions_winml.json and the
`FOUNDRY_LOCAL_USE_WINML` branch in FindOnnxRuntime.cmake /
FindOnnxRuntimeGenAI.cmake / the python build backend.
* Collapse cuda_ep_bootstrapper.cc to the single ORT-1.25.1 URL / binary
set (previously branched on WinML for the older 1.23.2 build).
* Drop the WebGPU-EP skip on WinML builds (both flavors now satisfy ORT
API >= 24).
* Drop the IsWindows11_24H2OrLater() runtime guard in
winml_ep_bootstrapper.cc; LoadLibraryW is a sufficient probe.
* Gate `find_package(WinMLEpCatalog)` behind `FOUNDRY_LOCAL_USE_WINML`
so non-WinML builds don't silently link the catalog DLL.
* CMake/cmake-modules: update DLL path
`runtimes-framework/<rid>/native/` -> `runtimes/<rid>/native/` and
bump default `WINML_EP_CATALOG_VERSION` to 2.1.6.
* Pipelines: bump `cppWinmlVersion` to 2.1.6, drop `cppOrtVersionWinml`
and the entire `Microsoft.WindowsAppSDK.Foundation` resolution +
Bootstrap.dll staging in steps-prefetch-nuget.yml /
steps-build-windows.yml.
* Nuget pack: replace `Microsoft.WindowsAppRuntime.Bootstrap.dll` with
`Microsoft.Windows.AI.MachineLearning.dll` in OPTIONAL_SIBLINGS.
* Bump gtest `DISCOVERY_TIMEOUT` to 60 for foundry_local_tests and
cache_only_tests; WinML's delay-loaded DLL resolution + static
initializers can exceed the 5 s default during test discovery.
Verified:
* `python sdk_v2/cpp/build.py --config RelWithDebInfo --skip_examples`
(non-WinML) builds clean; 820 unit/cache tests pass.
* `python sdk_v2/cpp/build.py --config RelWithDebInfo --skip_examples
--use_winml` builds clean; FindWinMLEpCatalog.cmake downloads
Microsoft.Windows.AI.MachineLearning 2.1.6 from nuget.org;
Microsoft.Windows.AI.MachineLearning.dll is co-located with
foundry_local.dll in the build output.
* Targeted ctest run on the WinML build:
`ctest -R "EpDetector|WinML|ManagerWebServiceTest|CacheOnlyTest"` ->
18/18 pass.
Out of scope (deferred): WebGPU manifest-based granular updates;
adopting WinML's bundled onnxruntime.dll.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The helper is only referenced from DiscoverProviders' EP-catalog code path. When FOUNDRY_LOCAL_HAS_EP_CATALOG=0 (non-WinML Windows build) the file is still compiled but the helper has no callers, which can trip MSVC C4505 (unreferenced local function has been removed) under /W4 builds. Moving the function definition inside the same preprocessor guard that gates its sole call site makes the compilation symmetric. No behavior change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The find-module advertised WINML_EP_CATALOG_HEADER_DIR as a public output (set as CACHE PATH ... FORCE and printed via message(STATUS)), but no caller in the repo reads it. Headers reach consumers through the WindowsML::Api target's INTERFACE_INCLUDE_DIRECTORIES, propagated by the WinMLEpCatalog::WinMLEpCatalog alias. The companion WINML_EP_CATALOG_DLL_DIR is genuinely consumed by the post-build DLL-copy step in sdk_v2/cpp/CMakeLists.txt, so only the header variable is dead. Drop the cache var, its STATUS line, and the corresponding header-block doc entry. Verified zero remaining references via 'git grep' and a clean configure + build of foundry_local on Windows. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Phase 3 design note still described the old fractional (0.0–1.0) progress contract that was removed when the artificial 99% cap was dropped. The current implementation in winml_ep_bootstrapper.cc treats WinML's progress value as a percentage (0–100) directly, matching the WinRT IAsyncOperationWithProgress<_, double> projection, and forwards it to the caller's percent callback after clamping — no scale conversion happens. Update the doc to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The EpDetector unions discovery results across CUDA / WebGPU / OpenVINO /
WinML bootstrappers; there is no caller-side fallback when WinML's
DiscoverProviders returns empty (Win10 19H1+ without 24H2, or DLL
missing) — the other bootstrappers were always going to run regardless.
- winml_ep_bootstrapper.h: drop the 'On earlier builds... caller falls back
to its other bootstrappers' sentences from the class doc. The preceding
two lines already state that EP discovery returns providers only on
Win11 24H2+, which is the only consumer-relevant fact.
- winml_ep_bootstrapper.cc: rewrite the LoadLibrary-failure comment to
drop 'older builds fall through to the other bootstrappers' for the
same reason; keep the OS-floor fact + diagnostics rationale.
- docs/EpDetectionPlan.md: rewrite the Risks/Mitigation entry the same
way ('returns empty when the DLL is missing — no WinML bootstrappers
join the discovery set').
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bindings that load foundry_local.dll from a non-default directory (JS prebuilds, Python wheels with FOUNDRY_LOCAL_LIB_DIR off, embedded C++ hosts that drop the runtime alongside their app binary) don't push that directory onto the process search path. A bare-name LoadLibraryW for Microsoft.Windows.AI.MachineLearning.dll then silently fails, the catalog returns zero providers, and DiscoverEps quietly returns only the always-on bootstrappers (CUDA + WebGPU) with no surfaced error. Resolve the sibling path explicitly via GetModuleHandleExW + GetModuleFileNameW + LOAD_WITH_ALTERED_SEARCH_PATH so the WinML DLL is found wherever foundry_local.dll lives. Fall back to the bare-name lookup so a system-installed copy still wins on the default search path when no sibling is present. Verified end-to-end against the dev build on Windows 11 24H2: cpp, cs, python, and js SDKs each return all 4 expected EPs (OpenVINO, NvTensorRTRTX, CUDA, WebGPU). The JS path previously returned only CUDA + WebGPU unless libraryPath was passed in FoundryLocalConfig. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
skottmckay
previously approved these changes
Jun 16, 2026
Aligns with neutron-server's WinML 2.0 dependency matrix. Both packages are published on NuGet. Updated in deps_versions.json (cmake source of truth), foundry-local-packaging.yml (pipeline literals), and the pipeline plan doc. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Respond to review feedback: testing net8.0 (LTS) is sufficient for CI. The library still multi-targets net8.0;net9.0;netstandard2.0 for packaging. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace fixed MAX_PATH stack buffer with a dynamically-grown std::wstring to support long paths (>260 chars) when the user has enabled them via the Windows registry or app manifest. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
94a0b85 to
41479a7
Compare
skottmckay
previously approved these changes
Jun 17, 2026
ORT's install_name is @rpath/libonnxruntime.1.dylib (major-version soname), but we only created the unversioned symlink. dyld couldn't find the library at test time on macOS arm64. Add the major-version symlink alongside the unversioned one. Co-authored-by: Copilot <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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Migrates WinML EP-download path from
Microsoft.WindowsAppSDK.ML1.8.2192 (WinML 1.x, requires the Windows App SDK bootstrap and Win11 24H2+) toMicrosoft.Windows.AI.MachineLearning2.1.70 (WinML 2.x, registration-free, Win10 19H1+)Highlights
IsWindows11_24H2OrLater()runtime guard inwinml_ep_bootstrapper.cc, sinceLoadLibraryWis a sufficient probe.find_package(WinMLEpCatalog)behindFOUNDRY_LOCAL_USE_WINMLso non-WinML builds don't silently link the catalog DLL.runtimes-framework/<rid>/native/→runtimes/<rid>/native/and bump defaultWINML_EP_CATALOG_VERSIONto 2.1.70.cppWinmlVersionto 2.1.70, dropcppOrtVersionWinmland the entireMicrosoft.WindowsAppSDK.Foundationresolution +Bootstrap.dllstaging insteps-prefetch-nuget.yml/steps-build-windows.yml.Microsoft.WindowsAppRuntime.Bootstrap.dllwithMicrosoft.Windows.AI.MachineLearning.dllinOPTIONAL_SIBLINGS.DISCOVERY_TIMEOUTto 60 s forfoundry_local_testsandcache_only_tests— the WinML build's delay-loaded DLL resolution + static initializers can exceed the 5 s default.net9.0-windows10.0.26100.0lock and targetsnet8.0;net9.0instead. The WinML 2.x OS floor (Win10 19H1+) is enforced at runtime bywinml_ep_bootstrapper.ccand by the EP catalog NuGet, not by the C# csproj, so consumers no longer need the Win11 24H2 SDK to build againstMicrosoft.AI.Foundry.Local.WinML.netstandard2.0is intentionally not added to the WinML SKU — the standard SKU keeps it (and thenet462test lane) for .NET Framework consumers; the WinML SKU's audience is Win11-era + modern .NET, so thenet462test lane is gated off for the WinML test matrix.WinML 2.x EP semantics (informational)
WinMLEpEnsureReadyAsync(WinMLAsyncBlock*), but the OS-side MSIX/BITS work is largely serialized anyway. Left as a future optimization.WinMLEpCatalogHandle) is only created during EnsureReady at the beginning. The 2.x C API has no Refresh/Invalidate, so if new EPs are released mid-process, they will only be visible after process restart.AzureModelCatalogcache is correctly invalidated inManager::DownloadAndRegisterEps(manager.cc:547) after a successful register, so model-filter results reflect the new EP set immediately.Maybe the extra error-checking in @sdk_v2/cpp/src/ep_detection/winml_ep_bootstrapper.cc is unnecessary, but I have added it for diagnostics.