Skip to content

Fix OpenVINO tests in CI - #24305

Closed
suryasidd wants to merge 5 commits into
pytorch:mainfrom
suryasidd:openvino_updates
Closed

suryasidd wants to merge 5 commits into
pytorch:mainfrom
suryasidd:openvino_updates

Conversation

@suryasidd

Copy link
Copy Markdown
Collaborator

Summary

Fixed 20 operator tests failing in the CI.

Test plan

Tested these tests locally and verified they are passing.

Copilot AI balanced review requested due to automatic review settings October 29, 2026 17:49
@pytorch-bot

pytorch-bot Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

🔗 Helpful Links

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

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

❌ 2 New Failures, 1 Unrelated Failure

As of commit de5b0a6 with merge base cd461b0 (image):

NEW FAILURES - The following jobs have failed:

BROKEN TRUNK - The following job failed but were present on the merge base:

👉 Rebase onto the `viable/strict` branch to avoid these failures

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 Oct 29, 2026
@github-actions

Copy link
Copy Markdown

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues are identified for the OpenVINO runtime and CI failure-reporting changes.

No open issues 🎉

What changed in this PR

This PR addresses OpenVINO operator test failures by adjusting runtime buffer handling and scalar tensor creation, and makes test failures visible to CI.

Changes:

  • Removes the explicit release of processed model data during backend initialization.
  • Handles rank-zero tensors without calling OpenVINO shape allocation or cleanup.
  • Returns a nonzero exit code when the test suite fails.
File Description
backends/​openvino/​tests/​test_runner.py Exits with status 1 on test failures so CI detects them.
backends/​openvino/​runtime/​OpenvinoBackend.cpp Adjusts model buffer lifetime and rank-zero tensor handling.

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 29, 2026 18:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues remain for the scalar-tensor handling and test-runner exit-status changes.

No open issues 🎉

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 29, 2026 20:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The scalar-tensor change needs API-contract confirmation or a scalar inference run to establish that supported OpenVINO C APIs accept rank=0 with dims=nullptr.

No open issues 🎉

Review effort: Balanced

@suryasidd
suryasidd requested a review from shoumikhin October 29, 2026 23:50

@shoumikhin shoumikhin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some notes inline.

device.assign(buf, len);
}
target = &device;
} else if (std::strcmp(compile_spec.key, "inference_precision") == 0) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The title and description read like a test-only fix, but this also changes the runtime that ships in the wheels. There is a new inference_precision compile spec that users can pass. And 0-d (scalar) tensors now work as delegate inputs and outputs, where before they failed. The test runner change matters too. Before, the OpenVINO job stayed green even when tests failed, so the failures were hidden. Now the job blocks pull requests on the op and model tests. Could you list these in the description and add the "release notes: openvino" label?

device.c_str(),
"INFERENCE_PRECISION_HINT",
inference_precision.c_str());
if (status != OV_STATUS_OK) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

OpenVINO does not check the value in ov_core_set_property. On a new core it only stores it, and checks it later, when the import loads the device plugin. So a typo such as fp32 never reaches this branch. With OpenVINO 2026.4.1 the import fails, init returns Internal, and OpenVINO's own message, which lists the supported values, is not logged. With 2025.1 the import succeeds and the value is quietly read as dynamic. The branch does fire for a device name OpenVINO rejects, but then the log blames the precision. Could we check the value up front (f32, f16, bf16) and return InvalidArgument, the way execute checks its arguments? Logging OpenVINO's error text when the import fails would also help.

}
}

// The device picks its default precision when the model is imported, e.g.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The precision hint is only applied when the model is loaded. That works on x86, where the CPU plugin picks the precision again at import. It does not work on ARM. There, compile_model already converts the weights to f16 at export, and the exported blob keeps them. preprocess.py drops inference_precision, so the export always uses the default. We tried a 512x512 f32 matmul exported on an ARM CPU. With inference_precision set to f32, the compiled model reports f32, but the error is the same as plain f16: about 0.36, where real f32 gives about 4e-5. A blob exported on x86 does not load on ARM, so ARM users always hit this, and the new test line does not fix the tolerance failures on an ARM machine. Could preprocess.py also pass the value to compile_model as INFERENCE_PRECISION_HINT? On ARM that brought the error down to 4e-5. Please keep the load time call too, because on x86 a hint given only at export is lost at import. The new comment about picking the precision at import would then need to say it is about x86. GPU and NPU blobs are probably fixed at export as well.

@shoumikhin

Copy link
Copy Markdown
Contributor

@claude /pr-review

@claude

claude Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Claude finished @shoumikhin's task in 17m 29s —— View job


Besides the open inline threads, I found five minor issues: the CI script stops before the model tests when an op test fails, OpenVINOTester doesn't get the f32 pin, the new inference_precision key isn't documented and a misspelled key is silently ignored, HETERO: devices likely break once the hint is set, and no test covers an invalid value.

Detailed review

PR Review: #24305

Summary

This PR adds an inference_precision compile spec that init() applies through ov_core_set_property. It also lets 0-d tensors through create_ov_tensor, pins the CPU op and model tests to f32, and makes test_runner.py exit non-zero on failure. Apart from the open inline threads, the issues below are all minor.

Code Quality

  • backends/openvino/runtime/OpenvinoBackend.cpp:349-353: the full device string is passed to ov_core_set_property.
    • OpenVINO's CoreImpl::set_property rejects names starting with HETERO: ("set_property is supported only for HETERO itself (without devices)"), and likewise MULTI:, AUTO: and BATCH:.
    • compile_model (preprocess.py:89) and import both accept HETERO:GPU,CPU.
    • So a .pte that loads today would fail init with InvalidArgument once inference_precision is added, and the log would blame the precision.
    • Fix: either reject that combination with a clear message, or set the hint on the underlying devices.
    • Lower priority: this comes from reading OpenVINO's source, not from a run against an installed OpenVINO, and the docs don't list composite devices.
    • Fix this →

Infrastructure

  • .ci/scripts/test_openvino.sh:8,15-16: the script runs under set -ex.
    • With the new sys.exit(1) (backends/openvino/tests/test_runner.py:75), one failing op test stops the script before --test_type models runs. Before this PR, both suites always ran.
    • Fix: record each exit code and keep going, as .ci/scripts/test_backend.sh:150-161 does (|| EXIT_CODE=$?, then exit $EXIT_CODE).
    • Fix this →
  • backends/openvino/test/tester/tester.py:46,74: OpenVINOTester still defaults to [CompileSpec("device", b"CPU")].
    • The nightly/release backend suite uses this tester (test-backend-openvino.yml → backends/test/suite/flows/openvino.py) with the same 1e-3 tolerances (backends/test/harness/tester.py:321-322).
    • It runs on mt-l-x86iavx512-16-128 (_test_backend.yml:43), the same runner family as this job's mt-l-x86iavx512-8-64 (pull.yml:1632). If those runners also default to bf16, that suite still has the same tolerance misses.
    • That workflow's pull_request path filter doesn't include backends/openvino/**, so this PR's CI can't show it.
    • Fix: add the hint to the tester defaults so both harnesses run at the same precision.
    • Fix this →

API Design

  • backends/openvino/runtime/OpenvinoBackend.cpp:330: inference_precision is a new contract between export and runtime, but it exists only as a bare string here and in one test.
    • Nothing documents the accepted values (OpenVINO element-type names), which devices honor it, or that it only takes effect at load.
    • No OpenVINO doc covers compile specs at all (backends/openvino/README.md, docs/source/build-run-openvino.md, examples/openvino/README.md).
    • Unknown keys are skipped silently in both preprocess.py:73-75 and init() (continue at line 333). So CompileSpec("INFERENCE_PRECISION_HINT", b"f32"), which is OpenVINO's own name for the property, exports and loads with no effect and no warning.
    • Fix: document the key, and consider warning on unknown keys in preprocess.py.
    • Fix this →

Testing

  • No test passes an invalid inference_precision or reaches the new error paths in init().
    • base_openvino_op_test.py:78-79 already loads through Runtime, so a case that exports with b"fp32" and asserts that load_method fails would lock in the validation asked for in the inline comment on line 354.
    • Fix this →

Recommendation

Request Changes

The main reason is the open inline threads:

  • preprocess.py:89 only passes device to compile_model, so the hint never reaches export-time compilation.
  • Invalid values aren't caught up front.

The items above are minor and can be fixed in the same pass.

shoumikhin added a commit that referenced this pull request Oct 31, 2026
The OpenVINO CI job runs backends/openvino/tests/test_runner.py. When a test
failed, the runner printed "completed with failures" but still exited with
code 0, so the CI job stayed green and the failure went unnoticed.

Now the runner exits with code 1 when any test fails, so CI turns red. This
is the test runner fix from #24305.

Co-authored-by: suryasidd <surya.siddharth.pemmaraju@intel.com>
shoumikhin added a commit that referenced this pull request Nov 2, 2026
…#24294 (#24396)

## What is wrong today

The OpenVINO partitioner gives `min`, `max`, `amin`, `amax`, `minimum`,
`maximum`, `clamp` and `sign` to OpenVINO even when every tensor they
read is bool. OpenVINO cannot convert these for bool:

```
ReduceMin ... Element type of data input must be numeric. Got: boolean
```

`torch.min(x > 0, dim=1)` and `MultivariateNormal`'s argument check
(PyTorch 2.15) hit this. Reading masked values after writing them fails
too:

```python
x[mask] = x[mask] * 2
return x + x[mask].sum()  # Dynamic rank for aten::index input is not supported.
```

## What this change does

The partitioner leaves these ops to ExecuTorch's CPU kernels when every
tensor they read is bool. Ops that also read a float tensor, like
`maximum(mask, x)`, stay with OpenVINO. Casting to uint8 could give
wrong `min(dim)` and `max(dim)` indices on ties, as the docs now note.

For the masked read, preprocess fills each node's `tensor_meta` from
`val`. OpenVINO reads ranks only from `tensor_meta`, which ExecuTorch
leaves empty.

Follow-ups to #24294:

- The test runner exits with 1 on failure (from #24305), and CI runs
model tests even after an op test fails.
- OpenVINO dropped a first input that only a folded `cumsum` read,
failing every call. Preprocess puts it back and checks the input count.
- An output planned as dynamic but compiled as fixed failed every call.
Its buffer now starts with the compiled shape.
- The `cumsum` fold works under a CUDA default device on a CPU-only
PyTorch (exir's ScalarToTensorPass still fails there).
- An empty last `inference_precision` entry now also means the default
at load.
- The docs say which CPUs compute some integer ops in float32, and where
the float32 default is slower.

## What was tested

Linux x86_64, OpenVINO 2026.4.1 and 2025.1.0, CPU, unless noted:

- Op and model tests pass. The bool `min` model (both releases) and the
masked read (2026.4.1) failed to lower, and now match eager.
- On 2026.4.1, each backend fix has a test that fails without it. The
runner and CI script were checked by hand.
- Partitions are unchanged for every probed op with integer, float16,
bfloat16 or float32 inputs, and for MobileNetV2, ResNet-18 and a
transformer layer.
- With the `tensor_meta` change, all other test partitions convert to
the same OpenVINO graphs.
- The docs' integer claims were measured on x86 through the delegate,
and on ARM with plain OpenVINO 2026.4.1.

---------

Co-authored-by: suryasidd <surya.siddharth.pemmaraju@intel.com>
@suryasidd

Copy link
Copy Markdown
Collaborator Author

These changes are addressed in #24294 and #24396. Closing this

@suryasidd suryasidd closed this Nov 3, 2026
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.

3 participants