ORT 1.28.1 Cherry Picks - #31966
Open
adrastogi wants to merge 3 commits into
Open
Conversation
### Description <!-- Describe your changes. --> Set `min_arity` of inputs to zero in EPContext node registration. ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> PR #28771 relaxed CompileModel validation to accept zero-input OrtModel graphs, so EpContext node should also accept zero-input.
### Description <!-- Describe your changes. --> Skip DXGI device discovery when Win32k system calls are disabled. DXGI internally calls `gdi32!DdQueryDisplaySettingsUniqueness`, which reads from the GDI shared memory section. Under Win32k lockdown this section may not be mapped (depending on the host's gdi32 initialization strategy), causing an access violation. ``` gdi32!DdQueryDisplaySettingsUniqueness+0x7: 00007ff8`30cf45f7 8b8090001800 mov eax,dword ptr [rax+180090h] ds:00000000`00180090=???????? # Child-SP RetAddr Call Site 00 00000072`4b5fc6f8 00007ff8`2b0f583e gdi32!DdQueryDisplaySettingsUniqueness+0x7 01 00000072`4b5fc700 00007ff8`2b0f433f dxgi!CDXGIFactory::SampleAdapters+0xae 02 00000072`4b5fc780 00007ff8`2b0f3f6a dxgi!CDXGIFactory::Initialize+0x10f 03 00000072`4b5fc870 00007ff8`2b0f34b8 dxgi!CreateDXGIFactoryImpl+0x9a 04 00000072`4b5fc8f0 00007fff`a9e08856 dxgi!CreateDXGIFactoryActualImpl2+0x58 05 00000072`4b5fc930 00007fff`a9e075c3 onnxruntime!onnxruntime::`anonymous namespace'::GetDeviceInfoD3D12+0x86 [device_discovery.cc @ 337] 06 00000072`4b5fcc10 00007fff`a9dec8a1 onnxruntime!onnxruntime::DeviceDiscovery::DiscoverDevicesForPlatform+0x323 [device_discovery.cc @ 584] 07 00000072`4b5fd000 00007fff`a9ded12e onnxruntime!`onnxruntime::DeviceDiscovery::GetDevices'::`2'::<lambda_1>::operator()+0x61 [device_discovery_common.cc @ 20] 08 00000072`4b5fd4c0 00007fff`a93b6c46 onnxruntime!onnxruntime::DeviceDiscovery::GetDevices+0x7e [device_discovery_common.cc @ 19] 09 00000072`4b5fd4f0 00007fff`a93b2d7d onnxruntime!onnxruntime::`anonymous namespace'::SortDevicesByType+0x36 [environment.cc @ 781] ``` ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> WebNN is migrating ORT graph compilation to a sandboxed process with PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY.DisallowWin32kSystemCalls enabled. This prevents calls through GDI for security hardening. This change has no effect on normal (unsandboxed) processes.
…ph transformation (#29681) Enable a compile-only session to run graph transformation (optimization + partitioning) and serialize the optimized model **without creating a device or touching hardware**. This supports offline / ahead-of-time compilation, where the optimized model is produced in a device-free (or sandboxed) process and executed later in a separate device-capable process. The serialized output reflects the requested graph-optimization level, including L2–L4 fusions. The feature targets WebGPU offline compilation and is driven by the Compile API's existing internal `session.compile_only` (`kOrtSessionOptionCompileOnly`) — **no new public config key**. The WebGPU-specific parts are the device-free context, the no-op allocator, and the virtual device; two of the mechanisms are EP-agnostic Compile-API improvements that benefit any EP: skipping session-state finalization (and returning early) for a compile-only session, and capturing the requested optimization level in the generated model. * **Device-free WebGPU context** (`webgpu_provider_factory.cc`, `webgpu_context.cc/.h`): in a compile-only session, skip Dawn adapter/device creation and all device-dependent init. `HasDevice()` exposes whether a real device exists; the mechanical "device-free" concept stays separate from the session concept "compile-only". * **Stop-before-finalize** (`inference_session.cc`): a compile-only session skips `FinalizeSessionState()` (kernel creation, initializer upload, memory planning — all need a device and are wasted for a throwaway session) and returns **before** the `optimized_model_filepath` save block. Its output is produced during graph transformation, not via that block. * **Capture the requested optimization level in the output** (`inference_session.cc`, `graph_partitioner.cc/.h`, `ep_context_utils.cc/.h`): the plain (non-EPContext) optimized model is serialized *after* the L2–L4 optimizer passes, so the emitted graph reflects the requested level (previously it was frozen at the partition boundary, before L2–L4). Serialization point is chosen by level: before the loop for `< Level2`, after all transforms for `>= Level2`. This is a general Compile-API fix; it does not change the output of compiling EPs, whose optimization lives in the EPContext blob. * **No-op allocator for device-free contexts** (`allocator.cc/.h`): every device-allocator construction site hands out `WebGpuNoOpAllocator` when there is no device, so ORT never builds a real allocator without one. * **Virtual GPU device** (`ep/factory.cc/.h`, internal `WebGpuEpFactory`): when no GPU `OrtHardwareDevice` is discovered and `allow_virtual_devices=1`, register a virtual GPU `OrtEpDevice` so the WebGPU EP stays selectable on hosts where device enumeration is unavailable (e.g. a sandbox). * **Build: delay-load `user32.dll`** (`cmake/onnxruntime.cmake`, `cmake/onnxruntime_providers_webgpu.cmake`) so the EP loads where `user32.dll` is unavailable but never actually needed (device discovery skipped). * Device-free compile-only session: `Initialize()` succeeds, `Run()` fails (non-runnable); no-op allocator handed out; virtual-device registration is deterministic with or without a GPU. * Plain optimized output through the **public Compile API** (`Ort::ModelCompilationOptions` + `Ort::CompileModel`) for the file, in-memory buffer, and user-write-func targets: asserts the emitted model is plain ONNX with no EPContext nodes, and that the requested optimization level is reflected in the output. Since the WebNN Compiler process is sandboxed, graph compilation within it must be offline / device-free: the untrusted model is parsed and graph-transformed in a low-privilege, device-free process, and the resulting model is executed later in a separate device-ful process. This is a **security** offload — it keeps untrusted-graph processing out of the high-privilege GPU process.
Tianlei Wu (tianleiwu)
approved these changes
Aug 10, 2026
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.
This cherry-picks the following commits for the release: