Skip to content

fix(genai): prefer device-native EPs over cross-device accelerators#1138

Merged
DingmaomaoBJTU merged 1 commit into
mainfrom
dingmaomaobjtu-fix-ov-ep-override-test
Jul 20, 2026
Merged

fix(genai): prefer device-native EPs over cross-device accelerators#1138
DingmaomaoBJTU merged 1 commit into
mainfrom
dingmaomaobjtu-fix-ov-ep-override-test

Conversation

@DingmaomaoBJTU

@DingmaomaoBJTU DingmaomaoBJTU commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

On OpenVINO hosts, resolve_genai_ep("cpu") incorrectly resolved to "openvino" instead of "cpu", causing test_device_cpu_overrides_device_and_ep to fail (born-broken since #1046).

Root Cause

resolve_eps("cpu") returns EPs in _DEVICE_EP_MAP priority order derived from EP_SUPPORTED_DEVICES declaration order. Since OpenVINOExecutionProvider declares ("npu", "gpu", "cpu") and appears before CPUExecutionProvider, the old code blindly took eps[0]"openvino".

Fix (generic)

Prefer EPs whose primary device (first entry in EP_SUPPORTED_DEVICES) matches the resolved device. Multi-device EPs like OpenVINO target npu primarily — when the user says --device cpu or --device gpu they expect the native EP, not a cross-device accelerator.

--device Before (OV host) After
cpu openvino cpu
gpu openvino (if OV first) dml/cuda
npu qnn/openvino unchanged (all primary=npu)

Falls back to eps[0] when no device-native EP is available.

Verification

  • Unit tests updated (11 pass, including new GPU cross-device case)
  • E2E test_device_cpu_overrides_device_and_ep passes on OV host
  • Ruff clean

@DingmaomaoBJTU
DingmaomaoBJTU requested a review from a team as a code owner July 20, 2026 02:47
@DingmaomaoBJTU
DingmaomaoBJTU force-pushed the dingmaomaobjtu-fix-ov-ep-override-test branch from a2117c8 to 0924ed1 Compare July 20, 2026 02:55
On OpenVINO hosts, resolve_genai_ep('cpu') incorrectly resolved to
'openvino' because OpenVINO advertises (npu, gpu, cpu) support and
appears before CPUExecutionProvider in the priority list.

Generic fix: prefer EPs whose *primary* device (first entry in
EP_SUPPORTED_DEVICES) matches the resolved device. Multi-device EPs
like OpenVINO target npu primarily — when the user says --device cpu
or --device gpu they expect the native EP, not a cross-device
accelerator that also happens to support it.

Examples:
  --device cpu  → CPUExecutionProvider (not OpenVINO)
  --device gpu  → DmlExecutionProvider (not OpenVINO/QNN)
  --device npu  → QNN/OpenVINO/VitisAI (unchanged, all primary=npu)

Falls back to eps[0] when no native EP is available.

Fixes the born-broken test_device_cpu_overrides_device_and_ep on OV
hosts (PR #1046).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@DingmaomaoBJTU DingmaomaoBJTU changed the title fix(genai): prefer CPUExecutionProvider when --device cpu is explicit fix(genai): prefer device-native EPs over cross-device accelerators Jul 20, 2026
@DingmaomaoBJTU
DingmaomaoBJTU merged commit 173b53f into main Jul 20, 2026
9 checks passed
@DingmaomaoBJTU
DingmaomaoBJTU deleted the dingmaomaobjtu-fix-ov-ep-override-test branch July 20, 2026 03:56
tezheng added a commit that referenced this pull request Jul 21, 2026
Resolve conflicts preferring branch features, with three deliberate
exceptions where main had the stronger change:

- check_ops.py / op_utils.py: drop the dead `sys_info` writer parameter
  (main's cleanup; it was collected but never persisted per its own comment).
- _perf_genai.py: adopt main's device-native EP preference (#1138) but return
  via the branch's `short_ep_name`/`EPNameOrAlias` idiom; cast str->EPName for
  the EP_SUPPORTED_DEVICES lookup.
- check_patterns.py: keep the branch's single-source-of-truth re-export of
  EP checkers from check_ops (required by test_ep_checker_dedup) plus main's
  RuntimeCheckerRulesPrefilter body; include main's additive NvTensorRTRTX
  choice (a GPU EP, outside the branch's NPU carve-out).

Also fix a pre-existing branch bug (fails identically on the pre-merge tip):
the winml-genai perf path passed the raw EpAtSourceParamType `(ep, source)`
tuple straight into GenaiPerfConfig.ep instead of the EP name. Unpack it like
the ONNX path does. Restores test_explicit_ep_overrides_device /
test_explicit_ep_without_device.

mypy (405 files) and ruff (src/ tests/) are green. This merge introduces zero
new test failures; the 20 remaining failures in analyze/build/perf CLI tests
are pre-existing and identical on the pre-merge tip (stale EP/device-resolution
mocks + one `tuple.device` bug in the build EP path).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants