Skip to content

Conversation

@olpipi
Copy link
Contributor

@olpipi olpipi commented Oct 20, 2025

Details:

  • Serialize any node as postponed constant

Tickets:

@olpipi olpipi added this to the 2025.4 milestone Oct 20, 2025
@olpipi olpipi added the pr: needs tests PR needs tests updating label Oct 20, 2025
@olpipi olpipi requested a review from a team as a code owner October 20, 2025 19:37
@github-actions github-actions bot added the category: Core OpenVINO Core (aka ngraph) label Oct 20, 2025
Comment on lines 920 to 971
{
// Collect all nodes with postponed_constant attribute (not for exclusion, but as starting points)
std::unordered_set<ov::Node*> postponed_constant_nodes;
for (const auto& node : sorted_ops) {
if (node->get_rt_info().count("postponed_constant")) {
postponed_constant_nodes.insert(node.get());
}
}

// Perform reverse DFS to find nodes that only feed into postponed_constant nodes
std::function<void(ov::Node*)> reverse_dfs = [&](ov::Node* node) {
// Skip if it's a Parameter (model input)
if (ov::op::util::is_parameter(node)) {
return;
}

// Check if ALL outputs go to postponed_constant or already excluded nodes
bool all_outputs_excluded = true;
for (const auto& output : node->outputs()) {
for (const auto& target_input : output.get_target_inputs()) {
auto* target_node = target_input.get_node();
if (!postponed_constant_nodes.count(target_node) && !nodes_to_exclude.count(target_node)) {
all_outputs_excluded = false;
break;
}
}
if (!all_outputs_excluded) {
break;
}
}

// If all outputs are excluded, mark this node and continue DFS
if (all_outputs_excluded && node->get_output_size() > 0) {
nodes_to_exclude.insert(node);
node->get_rt_info()["disabled_for_serialization"] = true;

// Recursively process all input nodes
for (const auto& input : node->inputs()) {
reverse_dfs(input.get_source_output().get_node());
}
}
};

// Start reverse DFS from all postponed_constant nodes
for (const auto& node : sorted_ops) {
if (node->get_rt_info().count("postponed_constant")) {
for (const auto& input : node->inputs()) {
reverse_dfs(input.get_source_output().get_node());
}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Could it be moved to separate function? XmlSerializer::serialize is already oversized.

Copy link
Contributor

Choose a reason for hiding this comment

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

All comment like // If all outputs are excluded, mark this node and continue DFS suggest that code could be extracted maybe not all as class members but some local helpers.

The serializer is used also by plugins to export compiled model e.g. CPU, also it wil be used by NPU mayeb this feature is not required at all in this cases and there should be possible to disable it at all e.g. by flag or override function

@olpipi olpipi changed the title Serialize any node as postponed constant [PoC]Serialize any node as postponed constant Oct 21, 2025
@olpipi olpipi force-pushed the postponed_constant_ext branch from 17250ca to 37d97d8 Compare October 23, 2025 08:58
@olpipi olpipi changed the title [PoC]Serialize any node as postponed constant Serialize any node as postponed constant Oct 23, 2025
@mryzhov
Copy link
Contributor

mryzhov commented Oct 23, 2025

@praasz , I think the better fix is #32502, are you sure that we need to merge the temp solution?
As it introduce new operation with not correct RTTI info and is more risk, also current usage solution using RT attribute is already in use so it will requires additional updates.

For CF is safer fix current solution this solution

@mlukasze
Copy link
Contributor

@praasz , I think the better fix is #32502, are you sure that we need to merge the temp solution? As it introduce new operation with not correct RTTI info and is more risk, also current usage solution using RT attribute is already in use so it will requires additional updates.

For CF is safer fix current solution this solution

as this is internal improvement we do prefer to go with this PR, there will be more to improve for next release, but also there will be more space to prepare proper solution.

@mryzhov mryzhov requested a review from Copilot October 24, 2025 08:48
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 implements serialization support for nodes marked as "postponed constants" by converting them to actual constants during model serialization and excluding their input subgraphs from the serialized output.

Key Changes:

  • Added logic to identify nodes marked with postponed_constant RT info and trace back through their input dependencies
  • Implemented subgraph exclusion for nodes that only feed into postponed constants
  • Modified edge serialization to handle port remapping for postponed constant nodes

Reviewed Changes

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

File Description
src/core/tests/pass/serialization/custom_ops.cpp Adds comprehensive test coverage for postponed constant serialization including concat operations, subgraph exclusion (skipped), multiple consumers, and parameter validation
src/core/src/xml_util/xml_serialize_util.cpp Implements core serialization logic with DFS-based subgraph exclusion and edge filtering for postponed constants

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +892 to +894
// Skip if it's a Parameter (model input)
if (ov::op::util::is_parameter(node)) {
return;
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

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

The check for Parameter nodes should include an exception throw when a Parameter is encountered in a postponed constant's dependency chain. Test ParameterNotExcluded expects an exception (line 313), but this implementation silently returns, preventing the exception from being raised.

Suggested change
// Skip if it's a Parameter (model input)
if (ov::op::util::is_parameter(node)) {
return;
// Throw if it's a Parameter (model input) in the dependency chain of a postponed constant
if (ov::op::util::is_parameter(node)) {
OPENVINO_THROW("Parameter node encountered in the dependency chain of a postponed constant, which is not allowed.");

Copilot uses AI. Check for mistakes.
}

// If all outputs are excluded, mark this node and continue DFS
if (all_outputs_excluded && node->get_output_size() > 0) {
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

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

The condition node->get_output_size() > 0 is checked after iterating over node->outputs() (line 899). If a node has zero outputs, the loop never executes and all_outputs_excluded remains true, but the node won't be excluded. This creates inconsistent behavior where nodes without outputs aren't excluded even though they have no consumers.

Suggested change
if (all_outputs_excluded && node->get_output_size() > 0) {
if (all_outputs_excluded) {

Copilot uses AI. Check for mistakes.
Comment on lines +242 to +244
// Expected: const1, const2 used for Add -> [6,8,10,12]
// Then multiply by const2 [5,6,7,8] -> [30,48,70,96]
// Then concat with const2 [5,6,7,8] along axis 0 -> [30,48,70,96,5,6,7,8] reshaped to {4,2}
Copy link

Copilot AI Oct 24, 2025

Choose a reason for hiding this comment

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

The expected computation comment is incorrect. The Add operation [1,2,3,4] + [5,6,7,8] produces [6,8,10,12], but the Multiply by [5,6,7,8] should yield [30,48,70,96]. However, the comment states this incorrectly as the result matches the provided expected values.

Copilot uses AI. Check for mistakes.
@mlukasze mlukasze added this pull request to the merge queue Oct 24, 2025
@praasz praasz removed this pull request from the merge queue due to a manual request Oct 24, 2025
@praasz praasz added this pull request to the merge queue Oct 24, 2025
Merged via the queue into openvinotoolkit:master with commit 79741b3 Oct 24, 2025
283 of 288 checks passed
@praasz praasz deleted the postponed_constant_ext branch October 24, 2025 15:58
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)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants