Skip to content

[OpenVINO] Enabling OpenVINO backend in test harness#17730

Open
suryasidd wants to merge 18 commits intopytorch:mainfrom
suryasidd:openvino_prod
Open

[OpenVINO] Enabling OpenVINO backend in test harness#17730
suryasidd wants to merge 18 commits intopytorch:mainfrom
suryasidd:openvino_prod

Conversation

@suryasidd
Copy link
Collaborator

Summary

  • This PR enables OpenVINO test flows into the test harness to enable operator tests and models tests on OpenVINO backend.
  • Also updates OpenVINO version to 2026.0
  • Added Qwen2.5 support

Copilot AI review requested due to automatic review settings February 26, 2026 04:39
@suryasidd suryasidd requested a review from cccclai as a code owner February 26, 2026 04:39
@pytorch-bot
Copy link

pytorch-bot bot commented Feb 26, 2026

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/17730

Note: Links to docs will display an error until the docs builds have been completed.

❌ 17 New Failures, 6 Cancelled Jobs, 1 Pending

As of commit 8d722b4 with merge base 331ac4a (image):

NEW FAILURES - The following jobs have failed:

CANCELLED JOBS - The following jobs were cancelled. Please retry:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Feb 26, 2026
@github-actions
Copy link

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR integrates the OpenVINO backend into the ExecuTorch backend test harness so operator/model suites can be exercised through new OpenVINO test flows and a dedicated CI workflow, while also updating the CI OpenVINO package version and adding an OpenVINO-specific preprocessing correctness pass.

Changes:

  • Add OpenVINO test flows (including an INT8/PTQ flow) and register them in the test suite flow registry.
  • Add OpenVINO tester plumbing (custom stages) and enable OpenVINO setup/build in CI test scripts + a scheduled workflow.
  • Add an OpenVINO preprocess pass to decompose div(rounding_mode="floor") into div + floor to match PyTorch semantics; extend quantize stage to plumb fold_quantize.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
backends/test/suite/flows/openvino.py Defines OpenVINO and OpenVINO INT8 test flows (with skip patterns).
backends/test/suite/flow.py Registers OpenVINO flows in all_flows() (but currently disables QNN registration).
backends/test/suite/conftest.py Skips tests early when a flow’s skip_patterns match the test name.
backends/test/harness/stages/quantize.py Adds fold_quantize option and forwards it into convert_pt2e.
backends/openvino/test/tester/tester.py Introduces OpenVINOTester and OpenVINO-specific stage implementations.
backends/openvino/test/tester/init.py Exports new OpenVINO tester symbols.
backends/openvino/scripts/openvino_build.sh Changes install invocation used by OpenVINO build script.
backends/openvino/runtime/OpenvinoBackend.cpp Adds scalar type mapping for Doublef64.
backends/openvino/preprocess.py Runs the new floor-divide decomposition pass during preprocess.
backends/openvino/partitioner.py Minor formatting change.
backends/openvino/_passes/decompose_floor_divide_pass.py Adds DecomposeFloorDividePass implementation.
backends/openvino/_passes/init.py Exposes the new pass from the package.
.github/workflows/test-backend-openvino.yml Adds a scheduled/on-demand OpenVINO backend CI workflow.
.github/workflows/_test_backend.yml Updates backend description to include OpenVINO.
.ci/scripts/test_backend.sh Adds OpenVINO environment setup + build flag for OpenVINO flows.
.ci/scripts/setup-openvino.sh Updates OpenVINO version/build used in CI setup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +121 to +140
# try:
# from executorch.backends.test.suite.flows.qualcomm import (
# QNN_16A16W_TEST_FLOW,
# QNN_16A4W_BLOCK_TEST_FLOW,
# QNN_16A4W_TEST_FLOW,
# QNN_16A8W_TEST_FLOW,
# QNN_8A8W_TEST_FLOW,
# QNN_TEST_FLOW,
# )

# flows += [
# QNN_TEST_FLOW,
# QNN_16A16W_TEST_FLOW,
# QNN_16A8W_TEST_FLOW,
# QNN_16A4W_TEST_FLOW,
# QNN_16A4W_BLOCK_TEST_FLOW,
# QNN_8A8W_TEST_FLOW,
# ]
# except Exception as e:
# logger.info(f"Skipping QNN flow registration: {e}")
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The QNN flow registration has been commented out here, which removes all Qualcomm flows from all_flows() and will stop the test suite from generating flow_qnn* parameters/markers. If the intent is to enable OpenVINO in addition to existing backends, please restore the QNN try: block and add OpenVINO as a separate block (or keep both), rather than leaving QNN disabled in commented code.

Suggested change
# try:
# from executorch.backends.test.suite.flows.qualcomm import (
# QNN_16A16W_TEST_FLOW,
# QNN_16A4W_BLOCK_TEST_FLOW,
# QNN_16A4W_TEST_FLOW,
# QNN_16A8W_TEST_FLOW,
# QNN_8A8W_TEST_FLOW,
# QNN_TEST_FLOW,
# )
# flows += [
# QNN_TEST_FLOW,
# QNN_16A16W_TEST_FLOW,
# QNN_16A8W_TEST_FLOW,
# QNN_16A4W_TEST_FLOW,
# QNN_16A4W_BLOCK_TEST_FLOW,
# QNN_8A8W_TEST_FLOW,
# ]
# except Exception as e:
# logger.info(f"Skipping QNN flow registration: {e}")
try:
from executorch.backends.test.suite.flows.qualcomm import (
QNN_16A16W_TEST_FLOW,
QNN_16A4W_BLOCK_TEST_FLOW,
QNN_16A4W_TEST_FLOW,
QNN_16A8W_TEST_FLOW,
QNN_8A8W_TEST_FLOW,
QNN_TEST_FLOW,
)
flows += [
QNN_TEST_FLOW,
QNN_16A16W_TEST_FLOW,
QNN_16A8W_TEST_FLOW,
QNN_16A4W_TEST_FLOW,
QNN_16A4W_BLOCK_TEST_FLOW,
QNN_8A8W_TEST_FLOW,
]
except Exception as e:
logger.info(f"Skipping QNN flow registration: {e}")

Copilot uses AI. Check for mistakes.

# Build the package
./install_executorch.sh --use-pt-pinned-commit
./install_executorch.sh --minimal
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching from --use-pt-pinned-commit to --minimal changes the PyTorch selection behavior (defaulting back to nightly) and can make OpenVINO builds/tests less reproducible. If the goal is to reduce dependencies, consider keeping the pinned PyTorch option while also using minimal installs (e.g., pass both flags or make it configurable).

Copilot uses AI. Check for mistakes.
cavusmustafa

This comment was marked as duplicate.

Copilot AI review requested due to automatic review settings February 26, 2026 06:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +77 to +95
opset = _get_opset(node.target)
a, b = node.args[0], node.args[1]

a_dtype = _node_dtype(a)
is_integer = a_dtype is not None and not a_dtype.is_floating_point

with graph.inserting_before(node):
if is_integer:
a_f = graph.call_function(
opset["to_copy"], (a,), {"dtype": torch.float32}
)
b_f = graph.call_function(
opset["to_copy"], (b,), {"dtype": torch.float32}
)
div_node = graph.call_function(opset["div"], (a_f, b_f))
floored = graph.call_function(opset["floor"], (div_node,))
result = graph.call_function(
opset["to_copy"], (floored,), {"dtype": a_dtype}
)
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DecomposeFloorDividePass decides the integer-vs-float rewrite based only on a's dtype and then casts the result back to a_dtype. This is incorrect for mixed-dtype cases where div would promote to a floating output (e.g. int / float) and also risks wrong semantics when dtype metadata is missing. Consider using the node's output dtype (node.meta['val'].dtype) or torch.result_type(a_val, b_val) to choose the rewrite, and only cast back when the output dtype is integral.

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +106
graph.eliminate_dead_code()
graph_module.recompile()
graph_module = super().call(graph_module).graph_module
return PassResult(graph_module, True)
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pass always returns PassResult(..., True) even if it didn't rewrite any nodes. That can cause unnecessary downstream work and makes pass pipelines harder to reason about. Track whether any div.Tensor_mode(..., rounding_mode='floor') nodes were replaced and return changed=False when none were found.

Copilot uses AI. Check for mistakes.
for pass_cls in [DimOrderOpsRevertPass, DecomposeFloorDividePass]:
result = pass_cls()(edge_program.graph_module)
if result and result.graph_module:
edge_program._graph_module = result.graph_module
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DecomposeFloorDividePass is now part of the OpenVINO preprocess pipeline, but there are no OpenVINO tests asserting correct floor-division semantics (especially for negative values where trunc vs floor differs). Please add a targeted unit/op test under backends/openvino/tests/ops that exercises torch.div(..., rounding_mode='floor') / torch.floor_divide on negative integer inputs and verifies OpenVINO output matches PyTorch.

Suggested change
edge_program._graph_module = result.graph_module
edge_program.graph_module = result.graph_module

Copilot uses AI. Check for mistakes.
Comment on lines 108 to +140
try:
from executorch.backends.test.suite.flows.qualcomm import (
QNN_16A16W_TEST_FLOW,
QNN_16A4W_BLOCK_TEST_FLOW,
QNN_16A4W_TEST_FLOW,
QNN_16A8W_TEST_FLOW,
QNN_8A8W_TEST_FLOW,
QNN_TEST_FLOW,
from executorch.backends.test.suite.flows.openvino import (
OPENVINO_INT8_TEST_FLOW,
OPENVINO_TEST_FLOW,
)

flows += [
QNN_TEST_FLOW,
QNN_16A16W_TEST_FLOW,
QNN_16A8W_TEST_FLOW,
QNN_16A4W_TEST_FLOW,
QNN_16A4W_BLOCK_TEST_FLOW,
QNN_8A8W_TEST_FLOW,
OPENVINO_TEST_FLOW,
OPENVINO_INT8_TEST_FLOW,
]
except Exception as e:
logger.info(f"Skipping QNN flow registration: {e}")
logger.info(f"Skipping OpenVINO flow registration: {e}")

# try:
# from executorch.backends.test.suite.flows.qualcomm import (
# QNN_16A16W_TEST_FLOW,
# QNN_16A4W_BLOCK_TEST_FLOW,
# QNN_16A4W_TEST_FLOW,
# QNN_16A8W_TEST_FLOW,
# QNN_8A8W_TEST_FLOW,
# QNN_TEST_FLOW,
# )

# flows += [
# QNN_TEST_FLOW,
# QNN_16A16W_TEST_FLOW,
# QNN_16A8W_TEST_FLOW,
# QNN_16A4W_TEST_FLOW,
# QNN_16A4W_BLOCK_TEST_FLOW,
# QNN_8A8W_TEST_FLOW,
# ]
# except Exception as e:
# logger.info(f"Skipping QNN flow registration: {e}")
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all_flows() no longer registers the Qualcomm/QNN flows (the entire QNN block is commented out), which will break QNN backend CI (e.g. test-backend-qnn.yml runs -m flow_qnn...) and removes QNN from the harness. Please restore the QNN flow registration and add the OpenVINO flows as an additional try-block rather than replacing QNN.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings February 26, 2026 07:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

pull_request:
paths:
- .github/workflows/test-backend-openvino.yml
- .github/workflows/_test_backend.yml
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pull_request.paths only watches workflow files, so changes to the OpenVINO backend/test harness (e.g. backends/openvino/**, .ci/scripts/**, backends/test/**) won’t trigger this workflow on PRs. This makes it easy for OpenVINO regressions to merge without any PR signal. Consider expanding paths similarly to other backend workflows (e.g. xnnpack) to include the relevant backend + harness directories.

Suggested change
- .github/workflows/_test_backend.yml
- .github/workflows/_test_backend.yml
- backends/openvino/**
- .ci/scripts/**
- backends/test/**

Copilot uses AI. Check for mistakes.
uses: ./.github/workflows/_test_backend.yml
with:
backend: openvino
flows: '["openvino"]'
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow only runs the openvino flow, but the PR also registers an openvino_int8 flow in the test harness. If INT8 is intended to be supported/kept green, consider adding it to the flows list here so it gets CI coverage (or document why it’s intentionally excluded).

Suggested change
flows: '["openvino"]'
flows: '["openvino", "openvino_int8"]'

Copilot uses AI. Check for mistakes.
Comment on lines 409 to +414
# Run the main function with parsed arguments
# Disable nncf patching as export of the patched model is not supported.
with nncf.torch.disable_patching():
main(
args.suite,
args.model,
args.input_shape,
args.export,
args.model_file_name,
args.quantize,
args.validate,
args.dataset,
args.device,
args.batch_size,
args.infer,
args.num_iter,
args.warmup_iter,
args.input_tensor_path,
args.output_tensor_path,
)
main(
args.suite,
args.model,
args.input_shape,
args.export,
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of nncf.torch.disable_patching() means this script now runs export/lowering without explicitly disabling NNCF’s Torch patching. Other OpenVINO-related examples in this repo still guard export with disable_patching() due to known side effects. If that concern still applies, consider reintroducing the context manager (or lazily importing nncf/quantize_model only when --quantize is used) to avoid export failures when NNCF is present.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants