Skip to content

Commit 4934aca

Browse files
bmehta001Copilot
andcommitted
Add WinML 2.0 preview samples
Add the WinML 2.0 verification samples and the minimal SDK, packaging, and target-framework support required to run them against the preview WinML stack. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 4ea0fca commit 4934aca

65 files changed

Lines changed: 2342 additions & 216 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.pipelines/templates/build-core-steps.yml

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ steps:
5858
inputs:
5959
command: restore
6060
projects: '$(nsRoot)/src/FoundryLocalCore/Core/Core.csproj'
61-
restoreArguments: '-r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.26100.0 /p:UseWinML=true'
61+
restoreArguments: '-r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.18362.0 /p:UseWinML=true'
6262
feedsToUse: config
6363
nugetConfigPath: '$(nsRoot)/nuget.config'
6464

@@ -67,14 +67,14 @@ steps:
6767
inputs:
6868
command: build
6969
projects: '$(nsRoot)/src/FoundryLocalCore/Core/Core.csproj'
70-
arguments: '--no-restore -r ${{ parameters.flavor }} -f net9.0-windows10.0.26100.0 /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.26100.0 /p:UseWinML=true'
70+
arguments: '--no-restore -r ${{ parameters.flavor }} -f net9.0-windows10.0.18362.0 /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.18362.0 /p:UseWinML=true'
7171

7272
- task: DotNetCoreCLI@2
7373
displayName: 'Publish FLC AOT ${{ parameters.flavor }} (WinML)'
7474
inputs:
7575
command: publish
7676
projects: '$(nsRoot)/src/FoundryLocalCore/Core/Core.csproj'
77-
arguments: '--no-restore --no-build -r ${{ parameters.flavor }} -f net9.0-windows10.0.26100.0 /p:Platform=${{ parameters.platform }} /p:Configuration=Release /p:PublishAot=true /p:NetTargetFramework=net9.0-windows10.0.26100.0 /p:UseWinML=true'
77+
arguments: '--no-restore --no-build -r ${{ parameters.flavor }} -f net9.0-windows10.0.18362.0 /p:Platform=${{ parameters.platform }} /p:Configuration=Release /p:PublishAot=true /p:NetTargetFramework=net9.0-windows10.0.18362.0 /p:UseWinML=true'
7878
publishWebProjects: false
7979
zipAfterPublish: false
8080

@@ -84,7 +84,7 @@ steps:
8484
inputs:
8585
command: restore
8686
projects: '$(nsRoot)/test/FoundryLocalCore/Core/FoundryLocalCore.Tests.csproj'
87-
restoreArguments: '-r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.26100.0 /p:UseWinML=true'
87+
restoreArguments: '-r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.18362.0 /p:UseWinML=true'
8888
feedsToUse: config
8989
nugetConfigPath: '$(nsRoot)/nuget.config'
9090

@@ -93,7 +93,7 @@ steps:
9393
inputs:
9494
command: build
9595
projects: '$(nsRoot)/test/FoundryLocalCore/Core/FoundryLocalCore.Tests.csproj'
96-
arguments: '--no-restore -r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.26100.0 /p:UseWinML=true'
96+
arguments: '--no-restore -r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.18362.0 /p:UseWinML=true'
9797

9898
- task: DotNetCoreCLI@2
9999
displayName: 'Test FLC ${{ parameters.flavor }} (WinML)'
@@ -170,18 +170,8 @@ steps:
170170
script: |
171171
$destDir = "$(Build.ArtifactStagingDirectory)/native"
172172
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
173-
# WinML publishes additional files (e.g. WindowsAppRuntime Bootstrapper DLLs)
174-
# beyond Microsoft.AI.Foundry.Local.Core.*.
175-
$isWinML = "${{ parameters.isWinML }}" -eq "True"
176-
if ($isWinML) {
177-
Get-ChildItem "$(nsRoot)/artifacts/publish" -Recurse -File |
178-
Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" -or $_.Name -eq "Microsoft.WindowsAppRuntime.Bootstrap.dll" } |
179-
Copy-Item -Destination $destDir -Force
180-
} else {
181-
Get-ChildItem "$(nsRoot)/artifacts/publish" -Recurse -File |
182-
Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" } |
183-
Copy-Item -Destination $destDir -Force
184-
}
173+
Get-ChildItem "$(nsRoot)/artifacts/publish" -Recurse -File |
174+
Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" } |
175+
Copy-Item -Destination $destDir -Force
185176
Write-Host "Staged binaries:"
186177
Get-ChildItem $destDir | ForEach-Object { Write-Host " $($_.Name)" }
187-

.pipelines/templates/package-core-steps.yml

Lines changed: 67 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ steps:
3939
'@
4040
$platforms = $platformsJson | ConvertFrom-Json
4141
42+
$isWinML = "${{ parameters.isWinML }}" -eq "True"
43+
4244
foreach ($p in $platforms) {
4345
$srcDir = "$(Pipeline.Workspace)/$($p.artifactName)"
4446
Write-Host "Looking for artifacts at: $srcDir"
@@ -47,22 +49,63 @@ steps:
4749
}
4850
$destDir = "$unifiedPath/runtimes/$($p.name)/native"
4951
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
50-
# WinML artifacts include WindowsAppRuntime Bootstrapper DLLs in addition
51-
# to Microsoft.AI.Foundry.Local.Core.*.
52-
$isWinML = "${{ parameters.isWinML }}" -eq "True"
53-
if ($isWinML) {
54-
Get-ChildItem $srcDir -File |
55-
Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" -or $_.Name -eq "Microsoft.WindowsAppRuntime.Bootstrap.dll" } |
56-
Copy-Item -Destination $destDir -Force
57-
} else {
58-
Get-ChildItem $srcDir -File | Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" } |
59-
Copy-Item -Destination $destDir -Force
60-
}
52+
Get-ChildItem $srcDir -File | Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" } |
53+
Copy-Item -Destination $destDir -Force
6154
Write-Host "Copied $($p.name) binaries to $destDir"
6255
}
6356
64-
# Copy build integration files from neutron-server
6557
$nsRoot = "$(nsRoot)"
58+
59+
if ($isWinML) {
60+
[xml]$propsXml = Get-Content "$nsRoot/Directory.Packages.props"
61+
$winMLVer = [string]$propsXml.Project.PropertyGroup.WinMLVersion
62+
if ([string]::IsNullOrWhiteSpace($winMLVer)) {
63+
throw "Directory.Packages.props is missing WinMLVersion."
64+
}
65+
66+
$runtimePackageDir = "$(Build.ArtifactStagingDirectory)/winml-runtime-package"
67+
New-Item -ItemType Directory -Path $runtimePackageDir -Force | Out-Null
68+
69+
$nugetArgs = @(
70+
'install', 'Microsoft.Windows.AI.MachineLearning',
71+
'-Version', $winMLVer,
72+
'-Source', 'https://api.nuget.org/v3/index.json',
73+
'-OutputDirectory', $runtimePackageDir,
74+
'-ExcludeVersion',
75+
'-NonInteractive',
76+
'-DirectDownload'
77+
)
78+
Write-Host "Running: nuget $($nugetArgs -join ' ')"
79+
& nuget $nugetArgs
80+
if ($LASTEXITCODE -ne 0) { throw "Failed to download Microsoft.Windows.AI.MachineLearning $winMLVer" }
81+
82+
$runtimePackageRoot = Get-ChildItem $runtimePackageDir -Directory |
83+
Where-Object { $_.Name -like "Microsoft.Windows.AI.MachineLearning*" } |
84+
Select-Object -First 1
85+
if (-not $runtimePackageRoot) {
86+
throw "nuget install did not produce a Microsoft.Windows.AI.MachineLearning package directory in $runtimePackageDir"
87+
}
88+
89+
foreach ($p in $platforms) {
90+
if (-not $p.name.StartsWith("win-")) {
91+
continue
92+
}
93+
94+
$runtimeDll = @(
95+
"$($runtimePackageRoot.FullName)/runtimes/$($p.name)/Microsoft.Windows.AI.MachineLearning.dll",
96+
"$($runtimePackageRoot.FullName)/runtimes/$($p.name)/native/Microsoft.Windows.AI.MachineLearning.dll"
97+
) | Where-Object { Test-Path $_ } | Select-Object -First 1
98+
if ([string]::IsNullOrWhiteSpace($runtimeDll)) {
99+
throw "Microsoft.Windows.AI.MachineLearning $winMLVer does not contain a Microsoft.Windows.AI.MachineLearning.dll for $($p.name)"
100+
}
101+
102+
$destDir = "$unifiedPath/runtimes/$($p.name)/native"
103+
Copy-Item $runtimeDll -Destination $destDir -Force
104+
Write-Host "Copied WinML runtime DLL for $($p.name) to $destDir"
105+
}
106+
}
107+
108+
# Copy build integration files from neutron-server
66109
foreach ($dir in @("build", "buildTransitive")) {
67110
$src = "$nsRoot/src/FoundryLocalCore/Core/$dir"
68111
if (Test-Path $src) {
@@ -100,10 +143,14 @@ steps:
100143
if ("${{ parameters.isWinML }}" -eq "True") {
101144
$nuspec = "$nsRoot/src/FoundryLocalCore/Core/WinMLNuget.nuspec"
102145
$id = "Microsoft.AI.Foundry.Local.Core.WinML"
103-
$ortVer = $pg.OnnxRuntimeFoundryVersionForWinML
104-
$genaiVer = $pg.OnnxRuntimeGenAIFoundryVersion
105-
$winAppSdkVer = $pg.WinAppSdkVersion
106-
$props = "id=$id;version=$(flcVersion);commitId=$(Build.SourceVersion);OnnxRuntimeFoundryVersionForWinML=$ortVer;OnnxRuntimeGenAIFoundryVersion=$genaiVer;WinAppSdkVersion=$winAppSdkVer"
146+
$ortVer = [string]$pg.OnnxRuntimeFoundryVersionForWinML
147+
$genaiVer = [string]$pg.OnnxRuntimeGenAIFoundryVersion
148+
$winMLVer = [string]$pg.WinMLVersion
149+
if ([string]::IsNullOrWhiteSpace($ortVer)) { throw "Directory.Packages.props is missing OnnxRuntimeFoundryVersionForWinML." }
150+
if ([string]::IsNullOrWhiteSpace($genaiVer)) { throw "Directory.Packages.props is missing OnnxRuntimeGenAIFoundryVersion." }
151+
if ([string]::IsNullOrWhiteSpace($winMLVer)) { throw "Directory.Packages.props is missing WinMLVersion." }
152+
153+
$props = "id=$id;version=$(flcVersion);commitId=$(Build.SourceVersion);OnnxRuntimeFoundryVersionForWinML=$ortVer;OnnxRuntimeGenAIFoundryVersion=$genaiVer;WinMLVersion=$winMLVer"
107154
} else {
108155
$nuspec = "$nsRoot/src/FoundryLocalCore/Core/NativeNuget.nuspec"
109156
$id = "Microsoft.AI.Foundry.Local.Core"
@@ -266,12 +313,13 @@ steps:
266313
elseif ($parts.Count -eq 2) { "$($parts[0])$($parts[1])" }
267314
else { $parts[0] }
268315
269-
# Both standard and WinML write a deps_versions.json with identical key
270-
# structure. The pipeline produces separate artifacts (deps-versions-standard
271-
# / deps-versions-winml) so SDK stages pick the right one via isWinML.
316+
# The pipeline produces separate dependency version artifacts
317+
# (deps-versions-standard / deps-versions-winml), so SDK stages pick the
318+
# right one via isWinML.
272319
if ($isWinML) {
273320
$deps = @{
274321
'foundry-local-core' = @{ nuget = "$(flcVersion)"; python = $pyVer }
322+
'windows-ai-machinelearning' = @{ version = [string]$pg.WinMLVersion }
275323
onnxruntime = @{ version = [string]$pg.OnnxRuntimeFoundryVersionForWinML }
276324
'onnxruntime-genai' = @{ version = [string]$pg.OnnxRuntimeGenAIFoundryVersion }
277325
}

.pipelines/templates/update-deps-versions-steps.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Shared template to update deps_versions.json / deps_versions_winml.json
2-
# from pipeline artifacts. Both files use identical key structure — the
3-
# isWinML parameter determines which file gets overwritten.
2+
# from pipeline artifacts. The isWinML parameter determines which file gets
3+
# overwritten.
44
parameters:
55
- name: repoRoot
66
type: string
@@ -39,3 +39,6 @@ steps:
3939
Write-Host " FLC Core (Python): $($deps.'foundry-local-core'.python)"
4040
Write-Host " OnnxRuntime: $($deps.onnxruntime.version)"
4141
Write-Host " GenAI: $($deps.'onnxruntime-genai'.version)"
42+
if ($isWinML -and $deps.'windows-ai-machinelearning') {
43+
Write-Host " Windows AI ML: $($deps.'windows-ai-machinelearning'.version)"
44+
}

samples/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ Explore complete working examples that demonstrate how to use Foundry Local —
88

99
| Language | Samples | Description |
1010
|----------|---------|-------------|
11-
| [**C#**](cs/) | 13 | .NET SDK samples including native chat, embeddings, audio transcription, tool calling, model management, web server, and tutorials. Uses WinML on Windows for hardware acceleration. |
12-
| [**JavaScript**](js/) | 13 | Node.js SDK samples including native chat, embeddings, audio transcription, Electron desktop app, Copilot SDK integration, LangChain, tool calling, web server, and tutorials. |
13-
| [**Python**](python/) | 10 | Python samples using the OpenAI-compatible API, including chat, embeddings, audio transcription, LangChain integration, tool calling, web server, and tutorials. |
14-
| [**Rust**](rust/) | 9 | Rust SDK samples including native chat, embeddings, audio transcription, tool calling, web server, and tutorials. |
11+
| [**C#**](cs/) | 14 | .NET SDK samples including native chat, embeddings, audio transcription, tool calling, model management, web server, tutorials, and WinML EP verification. Uses WinML on Windows for hardware acceleration. |
12+
| [**JavaScript**](js/) | 14 | Node.js SDK samples including native chat, embeddings, audio transcription, Electron desktop app, Copilot SDK integration, LangChain, tool calling, web server, tutorials, and WinML EP verification. |
13+
| [**Python**](python/) | 11 | Python samples using the OpenAI-compatible API, including chat, embeddings, audio transcription, LangChain integration, tool calling, web server, tutorials, and WinML EP verification. |
14+
| [**Rust**](rust/) | 10 | Rust SDK samples including native chat, embeddings, audio transcription, tool calling, web server, tutorials, and WinML EP verification. |
15+
| [**C++**](cpp/) | 2 | C++ SDK samples including WinML EP verification and live audio transcription. |
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
cmake_minimum_required(VERSION 3.20)
2+
3+
project(VerifyWinMLCpp LANGUAGES CXX)
4+
5+
set(BUILD_TESTING OFF CACHE BOOL "Build C++ SDK tests" FORCE)
6+
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../../sdk/cpp" "${CMAKE_CURRENT_BINARY_DIR}/sdk-cpp")
7+
8+
add_executable(VerifyWinML main.cpp)
9+
target_compile_features(VerifyWinML PRIVATE cxx_std_17)
10+
target_link_libraries(VerifyWinML PRIVATE CppSdk)

samples/cpp/verify-winml/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Verify WinML 2.0 Execution Providers (C++)
2+
3+
This sample verifies that WinML 2.0 execution providers are correctly
4+
discovered, downloaded, and registered using the Foundry Local C++ SDK. It then
5+
uses registered WinML EP-backed model variants and finishes with one native
6+
streaming chat check.
7+
8+
## Prerequisites
9+
10+
- Windows with a compatible GPU or NPU
11+
- A Foundry Local WinML native runtime copied next to the sample executable
12+
13+
The C++ SDK loads `Microsoft.AI.Foundry.Local.Core.dll` from the executable
14+
directory. Build or install a WinML-enabled SDK/runtime first, then copy the
15+
WinML native binaries next to `VerifyWinML.exe` before running the sample.
16+
17+
## Build
18+
19+
From this directory:
20+
21+
```powershell
22+
cmake -S . -B out\build -G "Visual Studio 18 2026" -A x64 `
23+
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" `
24+
-DVCPKG_TARGET_TRIPLET=x64-windows-static-md
25+
26+
cmake --build out\build --config Debug --target VerifyWinML
27+
```
28+
29+
## Run
30+
31+
```powershell
32+
.\out\build\Debug\VerifyWinML.exe
33+
```
34+
35+
## What it tests
36+
37+
1. **EP Discovery** - Lists all available execution providers.
38+
2. **EP Download & Registration** - Downloads and registers the available WinML EPs.
39+
3. **Model Catalog** - Lists text model variants backed by registered accelerated EPs.
40+
4. **Streaming Chat** - Runs streaming chat completion on a WinML EP-backed model via the native C++ SDK.

0 commit comments

Comments
 (0)