Skip to content

Fix stale bounds after AbsSinking via conditional invalidation in replace_output()#33288

Closed
evkotov wants to merge 12 commits intoopenvinotoolkit:masterfrom
evkotov:CVS-175062
Closed

Fix stale bounds after AbsSinking via conditional invalidation in replace_output()#33288
evkotov wants to merge 12 commits intoopenvinotoolkit:masterfrom
evkotov:CVS-175062

Conversation

@evkotov
Copy link
Copy Markdown
Contributor

@evkotov evkotov commented Dec 17, 2025

Details:

Problem
VIT model compilation fails with "Value for partial shape evaluation can't be lower than zero" because:

  • SymbolicPropagation sets SkipInvalidation attribute on tensors to prevent bounds recalculation during symbolic optimization
  • AbsSinking transformation modifies Concat inputs (inserts Abs before Concat)
  • Concat bounds are not invalidated due to SkipInvalidation, keeping stale values with -1
  • Broadcast shape inference receives stale bounds with -1 => assertion failure

Solution
Implement conditional bounds invalidation in replace_output():

  • Invalidate bounds when old source has bounds but new source doesn't (AbsSinking case - Abs output has no pre-computed bounds)
  • Invalidate bounds when both have bounds but they differ
  • Do not invalidate when bounds are the same (preserves OptimizeSymbolsUsedAsValues optimization)
  • New helper functions in bound_evaluation_util.hpp:
    tensors_equal() - compares two tensors for equality
    force_invalidate_bounds() - invalidates bounds bypassing SkipInvalidation attribute

Tickets:

  • 175062

@evkotov evkotov self-assigned this Dec 17, 2025
@evkotov evkotov requested review from a team as code owners December 17, 2025 15:51
@evkotov evkotov added the category: transformations OpenVINO Runtime library - Transformations label Dec 17, 2025
@github-actions github-actions bot added category: Core OpenVINO Core (aka ngraph) category: CPP API OpenVINO CPP API bindings labels Dec 17, 2025
@github-actions github-actions bot removed category: Core OpenVINO Core (aka ngraph) category: CPP API OpenVINO CPP API bindings labels Dec 18, 2025
@evkotov evkotov changed the title Add force_invalidate_values() to bypass SkipInvalidation flag Fix stale bounds in SymbolicOptimizations by clearing SkipInvalidation before SimplifyShapeOfSubGraph Dec 18, 2025
@evkotov evkotov requested a review from praasz December 18, 2025 15:11
@github-actions github-actions bot added the category: Core OpenVINO Core (aka ngraph) label Jan 13, 2026
@evkotov evkotov requested a review from praasz January 13, 2026 14:52
@evkotov evkotov changed the title Fix stale bounds in SymbolicOptimizations by clearing SkipInvalidation before SimplifyShapeOfSubGraph Fix stale bounds after AbsSinking via conditional invalidation in replace_output() Jan 13, 2026
@evkotov evkotov requested a review from mmikolajcz January 13, 2026 14:57
@praasz praasz self-assigned this Jan 13, 2026
}

bool ov::util::tensors_equal(const Tensor& a, const Tensor& b) {
// Both empty = equal
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.

is not duplicate of are_equal ?
This helper should do same.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No, it's not a duplicate. The key difference is in handling empty tensors

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.

are_equal also handles empty tensors, most of it is duplication.

// 1. Old had bounds but new doesn't have bounds (node was replaced with newly created one)
// 2. Both have bounds but they differ
bool should_invalidate = false;
if (old_has_bounds && !new_has_bounds) {
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.

These check looks like duplicate whe are_equal do.
Do we need check tensors or just check in new input and all input are not same tensors (without data check)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In OptimizeSymbolsUsedAsValues, we call evaluate_both_bounds() and then replace(). The old and new outputs point to different nodes but may have identical bound values (same shape data). Using are_same_tensor (pointer comparison via data()) would return false and trigger unnecessary invalidation.

@evkotov
Copy link
Copy Markdown
Contributor Author

evkotov commented Jan 15, 2026

Created #33622 with alternative approach

@evkotov evkotov closed this Jan 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: Core OpenVINO Core (aka ngraph) category: transformations OpenVINO Runtime library - Transformations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants