Skip to content

Python: onnxruntime-windowsml access violation in InferenceSession when a catalog EP (NvTensorRTRTX) is selected; same EP works under plain onnxruntime 1.30.0 #22

Description

@idocinthebox

Summary

onnxruntime-windowsml crashes with a native access violation inside InferenceSession(...) whenever an execution provider obtained from the Windows ML ExecutionProviderCatalog (here NvTensorRTRTXExecutionProvider, EP package 2.30.43.0) is registered with ort.register_execution_provider_library and selected for the session. Registration itself succeeds and the EP shows up in get_ep_devices(); the crash is at session creation, on every model tried, via both add_provider_for_devices and set_provider_selection_policy(PREFER_GPU).

The same EP DLL works when hosted by plain onnxruntime==1.30.0 (and by onnxruntime-directml==1.24.4), so the EP and the driver are fine; the failure is specific to the onnxruntime-windowsml wheel.

Environment

  • Windows 11, build 10.0.26200, x64
  • NVIDIA GeForce RTX 5070 Laptop GPU, driver 610.88
  • Python 3.12.10 (python.org, unpackaged), fresh venv
  • wasdk-Microsoft.Windows.AI.MachineLearning==2.3.0 (pins onnxruntime-windowsml==1.25.2.202605110140)
  • wasdk-Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap==2.3.0
  • Also reproduces with onnxruntime-windowsml==1.28.0.202607272323 installed over the pin
  • Windows App SDK runtime 2.3.x / 2.4.0 present; WindowsWorkload.WinMLShared.5.2 present
  • EP package: Microsoft.WinML.NVIDIA.TRT-RTX.EP.2_2.30.43.0_x64 (installed via ensure_ready_async(), status Success)
  • Model: SqueezeNet 1.0 opset 12 from the ONNX model zoo (validated/vision/classification/squeezenet/model/squeezenet1.0-12.onnx)

Repro

pip install "wasdk-Microsoft.Windows.AI.MachineLearning[all]" wasdk-Microsoft.Windows.ApplicationModel.DynamicDependency.Bootstrap onnxruntime-windowsml
python -X faulthandler repro.py squeezenet1.0-12.onnx

repro.py:

import os, sys, faulthandler; faulthandler.enable()
import onnxruntime as ort                      # crashes regardless of import order vs the bootstrap
from winui3.microsoft.windows.applicationmodel.dynamicdependency.bootstrap import initialize
CTX = initialize()
import winui3.microsoft.windows.ai.machinelearning as winml
p = [p for p in winml.ExecutionProviderCatalog.get_default().find_all_providers() if "NvTensorRT" in p.name][0]
assert int(p.ensure_ready_async().get().status) == 1
os.add_dll_directory(os.path.dirname(p.library_path))
ort.register_execution_provider_library(p.name, p.library_path)
nv = [d for d in ort.get_ep_devices() if d.ep_name == p.name]
print("registered:", [d.ep_name for d in ort.get_ep_devices()], flush=True)
so = ort.SessionOptions(); so.add_provider_for_devices(nv, {})   # policy PREFER_GPU crashes identically
s = ort.InferenceSession(sys.argv[1], sess_options=so)           # <- access violation here
print("session providers:", s.get_providers())

Observed

[W:onnxruntime:Default, onnxruntime_pybind_module.cc:45 onnxruntime::python::CreateOrtEnv] Init provider bridge failed.
registered: ['CPUExecutionProvider', 'DmlExecutionProvider', 'DmlExecutionProvider', 'NvTensorRTRTXExecutionProvider']
Windows fatal exception: access violation
Current thread ... (most recent call first):
  File "...\site-packages\onnxruntime\capi\onnxruntime_inference_collection.py", line 635 in _create_inference_session
  File "...\site-packages\onnxruntime\capi\onnxruntime_inference_collection.py", line 529 in __init__
  File "repro.py", line 14 in <module>

Exit code 0xC0000005. No Python traceback, no Windows Error Reporting entry.

With verbose ORT logging the last lines before the crash are the plugin EP's own creation messages:

[I:onnxruntime:, tensorrt_rtx_provider_factory.cc:802 ...CreateEpImpl] Creating Execution Provider
[I:onnxruntime:, tensorrt_rtx_execution_provider.cc:2098 ...] Plugin EP has been created with name NvTensorRTRTXExecutionProvider

Expected

A session using NvTensorRTRTXExecutionProvider, as happens with the same DLL under plain onnxruntime==1.30.0:

python ctrl.py squeezenet1.0-12.onnx
ort 1.30.0 providers ['NvTensorRTRTXExecutionProvider', 'CPUExecutionProvider'] output (1, 1000, 1, 1) finite True

(ctrl.py is the same script minus the bootstrap/catalog lines, registering the EP DLL by its absolute path.)

Notes that may help

  • The onnxruntime-windowsml wheel ships onnxruntime.dll and DirectML.dll in capi/ but no onnxruntime_providers_shared.dll, and every import prints Init provider bridge failed. Both wheels that work carry that DLL. Copying a 1.24.4 onnxruntime_providers_shared.dll next to the 1.25.2 runtime did not change the crash, so it may be a symptom rather than the cause.
  • ExecutionProvider.try_register() returns True but does not make the EP visible to the Python ORT env, as the docs say; register_execution_provider_library is what adds it.
  • library_path is empty until ensure_ready_async() has completed, even when ready_state is already NOT_READY rather than NOT_PRESENT.
  • CPU and DirectML sessions in the same wheel work normally (outputs bit-identical to onnxruntime-directml).

Activity

  1. adrastogi commented on Sep 14, 2026

    @adrastogi
    Collaborator

    Thanks for reporting this. This is a bit of a sharp edge with the Python language machinery. The winrt-runtime package includes an older VC redist that is not compatible with the ones needed by the execution provider which is why you are seeing this crash. The samples in the main Windows App SDK repository have a workaround to this effect. https://github.com/microsoft/WindowsAppSDK-Samples/blob/0057c23a44157b4cc8a539d52282a3d1f3559de8/Samples/WindowsML/python/SqueezeNetPython/winml.py#L46-L55

    In the case of your sample program, you could do something like this near the top:

    import ctypes
    import os
    
    # Keep the handle alive for the application's lifetime.
    _msvcp140 = ctypes.WinDLL(
        os.path.join(os.environ["SystemRoot"], "System32", "MSVCP140.dll")
    )
    
    # rest of imports and program logic
    

    If you try something like this, are you able to get your sample working?

  2. idocinthebox commented on Oct 3, 2026

    @idocinthebox
    Author

    Thanks adrastogi, that was it. Both workarounds fix the crash on every onnxruntime-windowsml build I tried.

    Results (same machine and SqueezeNet repro as above; the NVIDIA EP has since auto-updated to 2.30.49.0, Windows App Runtime 2.5.1 present):

    onnxruntime-windowsml as filed preload System32\MSVCP140.dll first remove winrt\msvcp140.dll (the sample's _fix_winrt_runtime)
    1.25.2.202605110140 access violation works works
    1.28.0.202607272323 access violation works works
    1.30.0.202609102321 access violation works works

    "Works" = a session with NvTensorRTRTXExecutionProvider is created and the output matches the CPU EP (max abs diff 1.1e-4, same top-1). One process per run, python -X faulthandler.

    What the loaded modules show (EnumProcessModulesEx at each step of the repro):

    • winrt-runtime 3.2.1 ships site-packages\winrt\msvcp140.dll 14.29.30157.0; System32 has 14.50.35719.0.
    • onnxruntime-windowsml links the C++ runtime statically (its onnxruntime.dll and .pyd import no msvcp140.dll), so importing it first loads no msvcp140 at all. The first one into the process is winrt's 14.29, loaded by _winrt.pyd.
    • onnxruntime_providers_nv_tensorrt_rtx.dll and tensorrt_plugins.dll import msvcp140.dll dynamically, so they bind to the 14.29 copy already loaded. That is the MSVC 17.10 std::mutex break (VCRuntime incompatibility with older version in mutex code STL#4730), which needs msvcp140 >= 14.40.
    • This is also why the same EP worked under onnxruntime 1.30.0 and onnxruntime-directml 1.24.4: those link msvcp140 dynamically, so importing ORT first puts System32's 14.50 in the process before winrt loads.
    • With EP 2.30.49.0 the unpatched repro now crashes one step earlier than in my report: inside ort.register_execution_provider_library(...), before any session exists. Same cause.

    The workaround in your comment (preload) and the one in the linked sample lines (deleting the DLL from winrt-runtime) are different. Both work here. I'm going with the preload because it doesn't modify an installed package.

    It looks like the same root cause as pywinrt/pywinrt#139 (closed after the delete-the-DLL workaround). Since winrt-runtime 3.2.1 is still the current release and the maintainer prefers to keep a bundled copy, a 14.40+ copy there, or the preload in the Python bootstrap package or the Windows ML Python docs, would save the next person this crash.

    The original "Init provider bridge failed" note was unrelated: it goes away when an onnxruntime_providers_shared.dll is present in capi, and it never affected the result.

    Fine to close this from my side, or keep it open for the packaging fix, as you prefer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions